Kotlin 协程(二)

183 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

前言

上一篇我们了解了协程的构造器和调度器,这一篇我们来了解一下常见的协程作用域。

协程作用域

在 Kotlin 中,协程必须在称为CoroutineScope的东西中运行。CoroutineScope 会跟踪协程,甚至是暂停的协程。为了确保跟踪所有协程,Kotlin 不允许在没有 CoroutineScope 的情况下启动新的协程。

全局作用域(GlobalScope)

  • 当协程在全局范围内启动时,它们的生命周期与应用程序一样长,除非是主进程退出否则只要该协程不结束就会一直占用资源,这样会出现很大的风险,比如说协程体中的代码出现异常,我们是无法释放的,这样就会造成设备资源异常消耗,从而内存泄漏应用崩溃。
  • 在全局范围内启动的协程将在单独的线程中启动,当存在多个协程时便会排队同步的执行,而不像多线程一样异步的争抢CPU资源。
 GlobalScope.launch(Dispatchers.Main) {
     val fA = async(Dispatchers.IO) { functionA() }
     val fB = async(Dispatchers.IO) { functionB() }
     // 返回UI线程
     functionC(fA.await(), fB.await()) 
}

生命周期作用域(LifeCycleScope)

具有生命周期的协程,是LifecycleOwner的扩展属性,是由Lifecycle Ktx库提供的能力,用于与具有生命周期感知的组件一起使用,生命周期销毁同时销毁该协程作用域,从而不会造成内存泄漏。

  • 引入
androidx.lifecycle:lifecycle-runtime-ktx:2.4.0
  • Activity中使用 由于Activity中实现了LifecycleOwner接口,所以可以在Activity中使用LifeCycleScope
class LifeCycleScopeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_layout)
	    //通过lifecycleScope创建协程
        lifecycleScope.launch {
         	// 执行相关的耗时业务逻辑
            ...
        }
    }
}

LifeCycleScope中默认的线程是主线程,我们可以通过其他方式来切换线程。

// 第一种
lifecycleScope.launch {
    withContext(Dispatchers.IO){
        // 执行相关的耗时业务逻辑
    	Logger.d("第一种${Thread.currentThread().name}")
    }
}

// 第二种
lifecycleScope.launch(Dispatchers.IO) {
    // 执行相关的耗时业务逻辑
    Logger.d("第二种${Thread.currentThread().name}")
}

ViewModel作用域( ViewModelScope)

为应用中的每个 ViewModel 定义了 ViewModelScope。如果 ViewModel 销毁会调用clear方法,然后调用CoroutineContextcancel方法,则在此范围内启动的协程都会自动取消。如果具有仅在 ViewModel 处于活动状态时才需要完成的工作,此时协程非常有用。

  • 引入
androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0
  • ViewModel中使用 由于ViewModel
class CoroutineViewModel : ViewModel() {
	fun functionA(){
		viewModelScope.launch(Dispatchers.IO) {
            // 执行业务逻辑
        }
    }
}