当前位置:   article > 正文

【深入理解Kotlin协程】lifecycleScope源码追踪扒皮_kotlin lifecyclescope

kotlin lifecyclescope

lifecycleScopeLifecycleOwner的扩展属性,而  ComponentActivity 和  Fragment(androidx)都实现了  LifecycleOwner 接口,所以这就是为什么说 lifecycleScope的作用范围是只能在Activity、Fragment中使用。
  1. public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
  2.     get() = lifecycle.coroutineScope

其中LifecycleOwner.lifecycleScope返回的是LifecycleOwnergetLifecycle().coroutineScope, coroutineScope又是Lifecycle的扩展属性:

  1. public val Lifecycle.coroutineScope: LifecycleCoroutineScope
  2.     get() {
  3.         while (true) {
  4.             val existing = mInternalScopeRef.get() as LifecycleCoroutineScopeImpl?
  5.             if (existing != null) {
  6.                 return existing
  7.             }
  8.             val newScope = LifecycleCoroutineScopeImpl(
  9.                 this,
  10.                 SupervisorJob() + Dispatchers.Main.immediate
  11.             )
  12.             if (mInternalScopeRef.compareAndSet(null, newScope)) {
  13.                 newScope.register()
  14.                 return newScope
  15.             }
  16.         }
  17.     }

lifecycleScope返回的是一个LifecycleCoroutineScopeImpl对象,而LifecycleCoroutineScope则是一个使用 SupervisorJob() + Dispatchers.Main.immediate 作为协程上下文的CoroutineScope对象。

LifecycleCoroutineScopeImpl的源码:
  1. internal class LifecycleCoroutineScopeImpl(
  2.     override val lifecycle: Lifecycle,
  3.     override val coroutineContext: CoroutineContext
  4. ) : LifecycleCoroutineScope(), LifecycleEventObserver {
  5.     init {
  6.         if (lifecycle.currentState == Lifecycle.State.DESTROYED) {
  7.             coroutineContext.cancel()
  8.         }
  9.     }
  10.     fun register() {
  11.         launch(Dispatchers.Main.immediate) {
  12.             if (lifecycle.currentState >= Lifecycle.State.INITIALIZED) {
  13.                 lifecycle.addObserver(this@LifecycleCoroutineScopeImpl)
  14.             } else {
  15.                 coroutineContext.cancel()
  16.             }
  17.         }
  18.     }
  19.     override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
  20.         if (lifecycle.currentState <= Lifecycle.State.DESTROYED) {
  21.             lifecycle.removeObserver(this)
  22.             coroutineContext.cancel()
  23.         }
  24.     }
  25. }

内部是通过  lifecycle.addObserver(this) 注册了 观察者对象,即将当前对象自身注册到了lifecycle对象中,当生命周期状态发生变化的时候,就会回调当前对象作为观察者的接口方法   onStateChanged() 。
     
在  onStateChanged() 方法中判断 lifecycle 当前的  state 如果小于等于  DESTROYED 就移除观察者并调用协程上下文的 cancel方法(这个方法中会查询当前上下文的Job对象调用其 cancel方法,从而取消协程)。
    
其中, Lifecycle.State是一个枚举类:
  1.  public enum State {
  2.      DESTROYED,   // 0
  3.      INITIALIZED, // 1
  4.    CREATED,     // 2
  5.      STARTED,     // 3
  6.      RESUMED;     // 4
  7.   public boolean isAtLeast(@NonNull State state) {
  8.          return compareTo(state) >= 0;
  9.      }
  10.  }

而 Activity和Fragment都实现了LifecycleOwner接口(可以通过getLifecycle()获取到Lifecycle的实例对象),在Activity和Fragment内部都实现了Lifecycle机制,Activity和Fragment对象中都有一个Lifecycle的实例对象LifecycleRegistry当Activity和Fragment生命周期函数变化时,会触发持有的Lifecycle实例对象的相关方法,改变对应的状态值,进而调用到其持有的观察者回调接口,即上面的LifecycleCoroutineScopeImpl对象里的onStateChanged()方法。并在其中判断如果是DESTROYED 状态就调用协程上下文的cancel方法取消协程。

因此, lifecycleScopeActivity执行 onDestroy()方法之后就会自动取消协程的原理真相就是如此。
      
我们说 lifecycleScope 只能在 Activity、Fragment 中使用其实是不太准确的。上面分析了  lifecycleScope是 LifecycleOwner 的扩展属性,Receiver 是 LifecycleOwner。因为Activity、Fragment和默认实现了LifecycleOwner,所以在其内部可以直接使用。但是理论上来说 只要是能获取到 LifecycleOwner 的地方都是可以使用 lifecycleScope 的!比如说从Activity、Fragment中创建的其他UI组件,只要是能获取Activity、Fragment对象的地方,那就可以间接地获取到LifecycleOwner。而像DialogFragment是Fragment的子类,自然也可以使用。
            
比如说LifecycleCoroutineScope内部就提供了几个方法, 当你不是在Activity、Fragment内部调用的时候,可以调用使用这几个方法:
  1. public abstract class LifecycleCoroutineScope internal constructor() : CoroutineScope {
  2.     internal abstract val lifecycle: Lifecycle
  3.     public fun launchWhenCreated(block: suspend CoroutineScope.() -> Unit): Job = launch {
  4.         lifecycle.whenCreated(block)
  5.     }
  6.     public fun launchWhenStarted(block: suspend CoroutineScope.() -> Unit): Job = launch {
  7.         lifecycle.whenStarted(block)
  8.     }
  9.     public fun launchWhenResumed(block: suspend CoroutineScope.() -> Unit): Job = launch {
  10.         lifecycle.whenResumed(block)
  11.     }
  12. }

内部其实是一个DispatchQueue封装了ArrayDeque队列。判断生命周期如果小于当前可执行的生命周期则加入队列,等到对应生命周期来到在取出执行。

但是有个问题就是使用这几个方法的时候没有办法设置异常处理器!直接启用了一个默认的launch,还没有给传入上下文的入口。 所以如果你想使用这几个方法还想传入异常处理器的话,可以这么做:自己写个launch。
  1. val coroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
  2.     throwable.printStackTrace()
  3. }
  4. lifecycleScope.launch(coroutineExceptionHandler) {
  5.     lifecycle.whenCreated {
  6.         // TODO:  
  7.     }
  8. }

Lifecycle原理机制

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/495661
推荐阅读
相关标签
  

闽ICP备14008679号