关于协程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
}
}
举个例子:
- 宿主Activity A ,包含FragmentB 、 FragmentC 两个Fragment
- FragmentB 和 FragmentC 根据相关的逻辑 可以随时Replace切换
- 此时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不太熟悉,所以导致了,这个问题。
刚刚仔细看了一遍,终于明白了。
不需要回答了。刚刚的问题是我没想明白
012021-04-27
相似问题