withContext(Dispatchers.IO) 与 viewModelScope.launch(Dispatchers.IO) 的区别

更新日期: 2023-05-19 阅读次数: 5508 字数: 470 分类: Android

CoroutineScope withContext lifecycleScope viewModelScope 该如何选择

CoroutineScope, withContext, lifecycleScope, 和 viewModelScope 是 Android 中用于协程管理的不同组件和类。这些组件和类可以帮助您在 Android 应用程序中正确地使用协程。

  • CoroutineScope:是一个顶层接口,用于管理协程以及它们运行的线程。您可以使用GlobalScope创建全局作用域,但通常建议为每个组件或任务创建自己的范围,以便在需要终止时可以更好地控制它们。
  • withContext:是一个Suspend函数,可用于在协程中切换上下文(线程)。它允许您在不阻塞UI线程的情况下执行长时间运行的代码,并将结果返回到主线程。
  • lifecycleScope:是Android Jetpack组件中的一部分,它提供了一个协程范围,该范围受到与组件生命周期相关的限制。例如,当Activity或Fragment被销毁时,此作用域也会自动清除。
  • viewModelScope:是Jetpack库中的ViewModel组件的一部分,适用于在ViewModel中启动协程。与lifecycleScope不同,此范围将保留ViewModel的生命周期,并在ViewModel被清除时取消其所有协程。

选择何种范围取决于您的需求。例如:

  • 如果您只是想在后台线程上执行一些长时间运行的代码,而无需与任何特定的生命周期相关,请使用CoroutineScope
  • 如果您需要在协程中切换上下文以避免阻塞UI线程,请使用withContext或其他CoroutineScope。
  • 如果您正在使用Android Jetpack库中的组件(如Activity或Fragment),并且要确保在组件被销毁时取消所有协程,请使用lifecycleScope
  • 如果您正在使用ViewModel,并且要确保在ViewModel被清除时取消其所有协程,请使用viewModelScope

viewModelScope 的作用

viewModelScope.launch(Dispatchers.IO) {
    // do something
}
  • viewModelScope 是一个内置的 CoroutineScope,包含在 ViewModel KTX 扩展中
  • Dispatchers.IO 是为了注明当前 coroutine 需要运行在一个用来执行 I/O 操作的线程中

当用户从一个界面退出,其对应的 ViewModel 会被销毁,相应的此 ViewModel 的 viewModelScope 会被自动取消 (cancelled),所有运行在 viewModelScope 中的 coroutine 也会被取消。

所以,没人会用 CoroutineScope.launch,原因就是当 UI 界面退出,但是 coroutine 运行时间过长,这个 coroutine 将得不到清理。

withContext(Dispatchers.IO) 与 viewModelScope.launch(Dispatchers.IO) 的区别

首先 withContext 也是一个 suspend function,所以 withContext 必须在 suspend 函数,或者 coroutine 中被调用。

  • viewModelScope.launch(Dispatchers.IO),即 launch 的 coroutine 运行之后,不再返回数据
  • withContext(Dispatchers.IO) 会将 coroutine 的返回值,作为当前函数的返回

例如:

suspend fun updatePage() {                      
    val result = getDataFromServer("www.sunzhongwei.com")  
    show(result)                               
}

suspend fun getDataFromServer(url: String) =                 
    withContext(Dispatchers.IO) {              
        // 执行网络请求          
    }                                          

viewModelScope 需要在 ViewModel 中使用

参考

https://medium.com/androiddevelopers/easy-coroutines-in-android-viewmodelscope-25bffb605471

参考

tags: ViewModel

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式