关于协程LifecycleCoroutineScope的疑问

来源:3-3 Lambda表达式

Da丶

2021-04-27

问题背景:

在Android中一般不推荐使用GlobalScope启动协程,Activity与Fragment都会包含对应的lifecycleScope

Activity -> lifecyclerOwner.lifecycleScope

Fragment -> viewLifecycleOwner.lifecycleScope

今天在实现需求时,突然想看下viewLifecycleOwner.lifecycleScope 是如何实现的,发现这段代码

public val Lifecycle.coroutineScope: LifecycleCoroutineScope
    get() {
        while (true) {
	        //如果已经存在创建好的LifecycleScope直接返回
            val existing = mInternalScopeRef.get() as LifecycleCoroutineScopeImpl?
            if (existing != null) {
                return existing
            }
            //如果不存在直接创建
            val newScope = LifecycleCoroutineScopeImpl(
                this,
                SupervisorJob() + Dispatchers.Main.immediate
            )
            if (mInternalScopeRef.compareAndSet(null, newScope)) {
                newScope.register()
                return newScope
            }
        }
    }

接着往下看

internal class LifecycleCoroutineScopeImpl(
    override val lifecycle: Lifecycle,
    override val coroutineContext: CoroutineContext
) : LifecycleCoroutineScope(), LifecycleEventObserver {
    init {
        // in case we are initialized on a non-main thread, make a best effort check before
        // we return the scope. This is not sync but if developer is launching on a non-main
        // dispatcher, they cannot be 100% sure anyways.
        //如果状态为DESTROYED,取消协程
        if (lifecycle.currentState == Lifecycle.State.DESTROYED) {
            coroutineContext.cancel()
        }
    }

    fun register() {
        launch(Dispatchers.Main.immediate) {
	          //注册状态变化监听
            if (lifecycle.currentState >= Lifecycle.State.INITIALIZED) {
                lifecycle.addObserver(this@LifecycleCoroutineScopeImpl)
            } else {
                coroutineContext.cancel()
            }
        }
    }

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
	    //状态变化成DESTROYED以下的状态,协程取消
        if (lifecycle.currentState <= Lifecycle.State.DESTROYED) {
            lifecycle.removeObserver(this)
            coroutineContext.cancel()
        }
    }
}

看到这里我有个疑问,老师我在获取coroutineScope时,如果Fragment的onCreateView方法还没有执行,是不是会一直阻塞在这里,等待Fragment创建View视图之后,才执行相对应的逻辑,那如果发生阻塞的话,极端异常情况下会不会引起UI的卡顿。

public val Lifecycle.coroutineScope: LifecycleCoroutineScope
    get() {
        while (true) {
			//xxxxxxxxxx
        }
    }

举个例子:

  1. 宿主Activity A ,包含FragmentB 、 FragmentC 两个Fragment
  2. FragmentB 和 FragmentC 根据相关的逻辑 可以随时Replace切换
  3. 此时Activity A 有个定时轮询,每固定间隔通过FragmentB FragmentC 实例访问,执行其方法
class ActivityA{
	
	var fragmentB :Fragment
	
	var fragmentC :Fragment 
	
	fun replace(){
		replace(FragmentB(),R.id.xxxxx)
	}
	
	fun tick(){
		fragmentB?.xxx()
		fragmentC?.xxx()
	}
}
class FragmentB{
	
	fun xxx(){
		viewLifecyclerOwner.lifecycleScope.launch{
			//执行相关逻辑
		}
	}
}

因为在ActivityA中我直接通过实例访问FragmentB、FragmentC

所以我觉得可能出现FragmentB的实例刚被创建,但是FragmentB的View还没创建好,如果这时候去获取scope,会不会阻塞,同时不知道会不会引起UI卡顿

写回答

1回答

Da丶

提问者

2021-04-27

抱歉老师,我刚刚重新看了下源码,我原来对LifecycleOwner不太熟悉,所以导致了,这个问题。

刚刚仔细看了一遍,终于明白了。

不需要回答了。刚刚的问题是我没想明白

0
1
Da丶
viewLifecyclerOwner 的使用只能够在View创建之后才可以使用
2021-04-27
共1条回复

Android首选开发语言Kotlin入门与进阶

Google I/O大会钦定Android一级开发语言,现在不学,等待何时

3122 学习 · 387 问题

查看课程