深入理解Kotlin协程lifecycleScope源码追踪扒皮
Posted 川峰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解Kotlin协程lifecycleScope源码追踪扒皮相关的知识,希望对你有一定的参考价值。
lifecycleScope是LifecycleOwner的扩展属性,而 ComponentActivity 和 Fragment(androidx)都实现了 LifecycleOwner 接口,所以这就是为什么说lifecycleScope的作用范围是只能在Activity、Fragment中使用。public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
get() = lifecycle.coroutineScope
其中LifecycleOwner.lifecycleScope返回的是LifecycleOwner的getLifecycle().coroutineScope, 而coroutineScope又是Lifecycle的扩展属性:
public val Lifecycle.coroutineScope: LifecycleCoroutineScope
get()
while (true)
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
lifecycleScope返回的是一个LifecycleCoroutineScopeImpl对象,而LifecycleCoroutineScope则是一个使用 SupervisorJob() + Dispatchers.Main.immediate 作为协程上下文的CoroutineScope对象。
LifecycleCoroutineScopeImpl的源码:internal class LifecycleCoroutineScopeImpl(
override val lifecycle: Lifecycle,
override val coroutineContext: CoroutineContext
) : LifecycleCoroutineScope(), LifecycleEventObserver
init
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)
if (lifecycle.currentState <= Lifecycle.State.DESTROYED)
lifecycle.removeObserver(this)
coroutineContext.cancel()
内部是通过 lifecycle.addObserver(this) 注册了观察者对象,即将当前对象自身注册到了lifecycle对象中,当生命周期状态发生变化的时候,就会回调当前对象作为观察者的接口方法 onStateChanged() 。
在 onStateChanged() 方法中判断 lifecycle 当前的 state 如果小于等于 DESTROYED 就移除观察者并调用协程上下文的cancel方法(这个方法中会查询当前上下文的Job对象调用其cancel方法,从而取消协程)。
其中,Lifecycle.State是一个枚举类:
public enum State
DESTROYED, // 0
INITIALIZED, // 1
CREATED, // 2
STARTED, // 3
RESUMED; // 4
public boolean isAtLeast(@NonNull State state)
return compareTo(state) >= 0;
而 Activity和Fragment都实现了LifecycleOwner接口(可以通过getLifecycle()获取到Lifecycle的实例对象),在Activity和Fragment内部都实现了Lifecycle机制,Activity和Fragment对象中都有一个Lifecycle的实例对象LifecycleRegistry,当Activity和Fragment生命周期函数变化时,会触发持有的Lifecycle实例对象的相关方法,改变对应的状态值,进而调用到其持有的观察者回调接口,即上面的LifecycleCoroutineScopeImpl对象里的onStateChanged()方法。并在其中判断如果是DESTROYED 状态就调用协程上下文的cancel方法取消协程。
因此,lifecycleScope在Activity执行onDestroy()方法之后就会自动取消协程的原理真相就是如此。 我们说 lifecycleScope 只能在 Activity、Fragment 中使用其实是不太准确的。上面分析了 lifecycleScope是 LifecycleOwner 的扩展属性,Receiver 是 LifecycleOwner。因为Activity、Fragment和默认实现了LifecycleOwner,所以在其内部可以直接使用。但是理论上来说只要是能获取到 LifecycleOwner 的地方都是可以使用 lifecycleScope 的!比如说从Activity、Fragment中创建的其他UI组件,只要是能获取Activity、Fragment对象的地方,那就可以间接地获取到LifecycleOwner。而像DialogFragment是Fragment的子类,自然也可以使用。 比如说LifecycleCoroutineScope内部就提供了几个方法,当你不是在Activity、Fragment内部调用的时候,可以调用使用这几个方法:public abstract class LifecycleCoroutineScope internal constructor() : CoroutineScope
internal abstract val lifecycle: Lifecycle
public fun launchWhenCreated(block: suspend CoroutineScope.() -> Unit): Job = launch
lifecycle.whenCreated(block)
public fun launchWhenStarted(block: suspend CoroutineScope.() -> Unit): Job = launch
lifecycle.whenStarted(block)
public fun launchWhenResumed(block: suspend CoroutineScope.() -> Unit): Job = launch
lifecycle.whenResumed(block)
内部其实是一个DispatchQueue封装了ArrayDeque队列。判断生命周期如果小于当前可执行的生命周期则加入队列,等到对应生命周期来到在取出执行。
但是有个问题就是使用这几个方法的时候没有办法设置异常处理器!直接启用了一个默认的launch,还没有给传入上下文的入口。所以如果你想使用这几个方法还想传入异常处理器的话,可以这么做:自己写个launch。val coroutineExceptionHandler = CoroutineExceptionHandler coroutineContext, throwable ->
throwable.printStackTrace()
lifecycleScope.launch(coroutineExceptionHandler)
lifecycle.whenCreated
// TODO:
Lifecycle原理机制
其实单独看lifecycleScope的源码定义就只有两层皮,人家一下子就被你看光了,但是当你看完之后,貌似心里还是不太踏实,不是说它会在页面销毁时自动取消吗?那具体的生命周期它是怎么感知的呢?既然都扒到Lifecycle了,那就顺便对它也扒一下皮吧。。 先简单看一下Lifecycle的使用。 首先 androidx 的 ComponentActivity 和 Fragment 都实现了 LifecycleOwner 接口,这个接口中就只有一个方法:public interface LifecycleOwner
@NonNull
Lifecycle getLifecycle();
因此可以在Activity 和 Fragment 中调用这个方法getLifecycle(),这个方法会返回Lifecycle的实例对象。
Lifecycle的主要方法:public abstract class Lifecycle
public abstract void addObserver(LifecycleObserver observer);
public abstract void removeObserver(LifecycleObserver observer);
public abstract State getCurrentState();
public enum Event
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
public static Event downFrom(State state) ...
public static Event downTo(State state) ...
public static Event upFrom(State state) ...
public static Event upTo(State state) ...
public State getTargetState() ...
public enum State
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(State state)
return compareTo(state) >= 0;
Lifecycle中有一个添加观察者的方法和一个移除观察者的方法,然后就是两个枚举类Event和State, 分别对应不同的生命周期的方法和状态,剩下就是一些状态流转的操作方法。
因此可以Activity或Fragment调用:getLifecycle().addObserver(new MyLifecycleObserver())
然后定义一个LifecycleObserver接口的实现类即可:
public class MyLifecycleObserver implements LifecycleEventObserver
private final static String TAG = MyLifecycleObserver.class.getSimpleName();
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event)
Log.e(TAG, "onStateChanged 事件来源:"+source.getClass().getName());
switch (event)
case ON_CREATE:
Log.e(TAG, "onStateChanged: ON_CREATE");
break;
case ON_START:
Log.e(TAG, "onStateChanged: ON_START");
break;
case ON_RESUME:
Log.e(TAG, "onStateChanged: ON_RESUME");
break;
case ON_PAUSE:
Log.e(TAG, "onStateChanged: ON_PAUSE");
break;
case ON_STOP:
Log.e(TAG, "onStateChanged: ON_STOP");
break;
case ON_DESTROY:
Log.e(TAG, "onStateChanged: ON_DESTROY");
break;
case ON_ANY:
Log.e(TAG, "onStateChanged: ON_ANY");
break;
default:
break;
其中LifecycleEventObserver继承了LifecycleObserver,而LifecycleObserver是一个空接口:
public interface LifecycleEventObserver extends LifecycleObserver
void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
public interface LifecycleObserver
当Activity生命周期方法变化时,onStateChanged方法就会回调,其中方法参数source表示事件来源,event表示当前触发的生命周期事件。
使用真的非常简单。
接下来看一下 ComponentActivity的getLifecycle方法返回的是什么:
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner ...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
...
public Lifecycle getLifecycle()
return mLifecycleRegistry;
可以看到就是一个LifecycleRegistry类的全局成员变量,而LifecycleRegistry类正是Lifecycle接口的实现类:
public class LifecycleRegistry extends Lifecycle
public LifecycleRegistry(LifecycleOwner provider)
this(provider, true);
private LifecycleRegistry(LifecycleOwner provider, boolean enforceMainThread)
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
mEnforceMainThread = enforceMainThread;
LifecycleRegistry通过弱引用持有了LifecycleOwner的对象,也就是Activity对象
addObserver()方法的实现:@Override
public void addObserver(@NonNull LifecycleObserver observer)
//检查是否在主线程
enforceMainThreadIfNeeded("addObserver");
//设置初始状态值
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//将观察者和初始化的状态值封装到ObserverWithState中
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//以观察者为key,statefulObserver为value放到hashMap集合中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//不为null表示之前已经放进去了,否则没放进去,放进去了就添加结束
if (previous != null)
return;
//获取被观察者对象,即Activity,如果被销毁了,则结束
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null)
// it is null we should be destroyed. Fallback quickly
return;
//mAddingObserverCounter 表示正在添加的观察者的数量,
//开始添加新的observe之前,对该变量进行++操作,添加完成后,进行--操作。
//mHandlingEvent表示是否正在处理
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//计算状态,进行while循环
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//新添加的LifecycleObserver ,会不断更新自己的生命周期到指定的targetState
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer)))
//添加状态到list,计算当前状态,用于计算状态calculateTargetState
pushParentState(statefulObserver.mState);
//
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null)
throw new IllegalStateException("no event up from " + statefulObserver.mState);
//生命周期分发:分发到mLifecycleObserver里面
statefulObserver.dispatchEvent(lifecycleOwner, event);
//移除状态到list
popParentState();
// mState / subling may have been changed recalculate
//重新计算状态
targetState = calculateTargetState(observer);
//没有事件正在处理,或者是添加了observe,就需要重新同步一次状态,下面详细介绍
if (!isReentrance)
// we do sync only on the top level.
sync();
mAddingObserverCounter--;
//计算状态规则
private State calculateTargetState(LifecycleObserver observer)
//在map中获取到当前observer的前一个observer
Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
//前一个observer的state
State siblingState = previous != null ? previous.getValue().mState : null;
//如果是嵌套添加observer,获取父级observer的状态
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
//获取最小状态,DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED
return min(min(mState, siblingState), parentState);
Activity的生命周期如何通过LifecycleRegistry触发
触发的原理已经不是什么新鲜事了,就是在Activity的onCreate()方法中添加了一个透明的Fragment来专门处理生命周期:ReportFragment.injectIfNeededIn(this);
public class ReportFragment extends android.app.Fragment
public static void injectIfNeededIn(Activity activity)
if (Build.VERSION.SDK_INT >= 29)
// 在 API 29+ 以上, 可以直接注册Activity的生命周期回调接口
LifecycleCallbacks.registerIn(activity);
// 以下是兼容 API 29 以前的版本
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null)
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
先看 API >= 29 的处理,LifecycleCallbacks.registerIn方法的实现:
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks
static void registerIn(Activity activity)
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
@Override
public void onActivityCreated(Activity activity, Bundle bundle)
@Override
public void onActivityPostCreated(Activity activity, Bundle savedInstanceState)
dispatch(activity, Lifecycle.Event.ON_CREATE);
@Override
public void onActivityStarted(Activity activity)
@Override
public void onActivityPostStarted(Activity activity)
dispatch(activity, Lifecycle.Event.ON_START);
....省略其他方法,跟上面 onCreated 和 onStarted 的处理雷同
可以看到就是为Activity注册一个Application.ActivityLifecycleCallbacks的回调接口实现类,如继续追踪下去就会发现这个Callback被Actvity内部保存了起来。(注意这个保存的Activity直接就是android.app.Activity,而不是androidx.activity.ComponentActivity,也就是说高版本直接在最顶层的Activity类中处理了,不论什么xxxActivity都生效)
然后看看Actvity内部什么时候调用注册的这个Callback,不出意外的话肯定会在生命周期方法中调用,所以我们随便找一个onStart()方法来看一下:protected void onStart()
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
mCalled = true;
mFragments.doLoaderStart();
dispatchActivityStarted();
getAutofillClientController().onActivityStarted();
发现这里有个 dispatchActivityStarted() 方法,继续追踪下去:
private void dispatchActivityStarted()
getApplication().dispatchActivityStarted(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null)
for (int i = 0; i < callbacks.length; i++)
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityStarted(this);
可以看到这里进行遍历保存的所有Callback对象的回调方法进行回调,其他生命周期方法处理也是类似的。回到LifecycleCallbacks中我们发现onActivityStarted的实现是空的,没有做事情,而是在onActivityPostStarted中处理的,因此我们再去Activity中看看onActivityPostStarted在什么时候调用:
final void performStart(String reason)
....
dispatchActivityPostStarted();
private void dispatchActivityPostStarted()
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null)
for (int i = 0; i < callbacks.length; i++)
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStarted(this);
getApplication().dispatchActivityPostStarted(this);
最终是由Activity的performStart()触发的,但是在当前类范围内找不到调用它的地方了,那是在哪里调用的performStart()?答案是在ActivityThread类中调用的:
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, ActivityOptions activityOptions)
...
activity.performStart("handleStartActivity");
但是ActivityThread中的这个handleStartActivity方法又是哪里调用的呢?答案是由ATMS(ActivityStackManagerService)跨进程调用的,这里涉及Android 10.0以上Activity启动流程了,流程比较长就不展开了,总而言之,会由ATMS向应用端进程发起Binder调用, 然后通过如下路径进行处理:
ApplicationThread.scheduleTransaction() -> ActivityThread.scheduleTransaction()(在其父类中) -> mH.sendMessage(H.EXECUTE_TRANSACTION, ClientTransaction) -> H.handleMessage(EXECUTE_TRANSACTION) -> TransactionExecutor.execute(transaction) -> executeLifecycleState(transaction) -> cycleToPath(r, lifecycleItem.getTargetState(), true , transaction) -> performLifecycleSequence(r, path, transaction) -> ON_START -> mTransactionHandler.handleStartActivity(r, mPendingActions, null) -> ActivityThread.handleStartActivity() -> activity.performStart() 补充一张Android 10.0 Activity应用内启动流程图和LifecycleState管理相关的类图,这两个图都是别人总结的,我觉得还不错的,所以贴出来。(请点击放大看)再次回到ReportFragment的LifecycleCallbacks中:
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks
...
@Override
public void onActivityPostStarted(@NonNull Activity activity)
dispatch(activity, Lifecycle.Event.ON_START);
...
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event)
if (activity instanceof LifecycleRegistryOwner)
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
if (activity instanceof LifecycleOwner)
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry)
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
dispatch方法就是简单的判断当前如果是LifecycleOwner就获取到其持有的LifecycleRegistry对象,然后调用其handleLifecycleEvent方法:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event)
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
private void moveToState(State next)
...
sync();
mHandlingEvent = false;
if (mState == DESTROYED)
mObserverMap = new FastSafeIterableMap<>();
最终会调用LifecycleRegistry对象的sync()方法:
private void sync()
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null)
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
//没有同步过,则同步
while (!isSynced())
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0)
//如果ObserverWithState的state小于当前state,那么就调用forwardPass方法,
backwardPass(lifecycleOwner);
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0)
//如果大于当前state,那么就调用backwardPass方法。
forwardPass(lifecycleOwner);
mNewEventOccurred = false;
其中 backwardPass和forwardPass方法都会调用 observer.dispatchEvent(lifecycleOwner, event) 也就是ObserverWithState这个包装类的dispatchEvent方法:
static class ObserverWithState
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState)
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
void dispatchEvent(LifecycleOwner owner, Event event)
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
这里最终会回调我们最开始使用例子中为其注册的LifecycleEventObserver这个观察者对象的onStateChanged()接口方法,到此就破案了。
以上就是 API >= 29 的处理逻辑,接下来继续来继续看 API < 29 的处理逻辑,那就只能是在ReportFragment的生命周期方法里了,我们还是挑一个onStart方法看看:@Override
public void onStart()
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
private void dispatch(@NonNull Lifecycle.Event event)
if (Build.VERSION.SDK_INT < 29)
// Only dispatch events from ReportFragment on API levels prior
// to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
// added in ReportFragment.injectIfNeededIn
dispatch(getActivity(), event);
可以看到这里注释也说明了,只有 API < 29 的才走这个地方,但是这个dispatch方法点进去看,其实就是前面已经分析过的dispatch方法,所以这里最终殊途同归,也是调用ObserverWithState这个包装类的dispatchEvent方法里,进而回调LifecycleEventObserver的onStateChanged()接口方法。
以上就是Activity的生命周期如何通过LifecycleRegistry触发的真相。 接下来再看看,普通的Fragment中是如何处理生命周期通过LifecycleRegistry触发的:public Fragment()
initLifecycle();
private void initLifecycle()
mLifecycleRegistry = new LifecycleRegistry(this);
...
public Lifecycle getLifecycle()
return mLifecycleRegistry;
Fragment的getLifecycle()也是返回的LifecycleRegistry对象,这个对象是在Fragment()构造函数中就初始化的。直接在Fragment中全局搜索一下这个对象就会发现:
void performStart()
mChildFragmentManager.noteStateNotSaved();
mChildFragmentManager.execPendingActions(true);
mState = STARTED;
mCalled = false;
onStart();
if (!mCalled)
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onStart()");
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
if (mView != null)
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
mChildFragmentManager.dispatchStart();
很明显在performStart()方法中进行了处理,这个handleLifecycleEvent()方法就是我们前面分析过的,所以跟前面Activity的最终处理逻辑路径又殊途同归了。
现在就剩下一个问题:Fragment.performStart()方法是在哪里调用的?答案不用想肯定是FragmentActivity中,因为我们知道Fragment要依赖一个FragmentActivity对象作为宿主,然后Fragment使用时肯定是被添加到FragmentManager中的,所以自然而然就找到了调用的地方。由于调用流程太长,不展开了直接贴出追踪路径如下: FragmentActivity.onStart() -> FragmentController.dispatchStart() -> mHost.mFragmentManager.dispatchStart() -> dispatchStateChange(Fragment.STARTED) -> moveToState(nextState, false) -> startPendingDeferredFragments() -> performPendingDeferredStart(fragmentStateManager) -> fragmentStateManager.moveToExpectedState() -> Fragment.STARTED -> start() -> mFragment.performStart() 至此,我们的Lifecycle的皮就扒完了,以后不管是使用lifecycleScope还是直接使用Lifecycle时,就能做到心中有数。以上是关于深入理解Kotlin协程lifecycleScope源码追踪扒皮的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin之协程coroutine lifecycleScope 和 viewModelScope源码