开局一个问题
请问ViewModel#onCleared的回调和Activity#onDestoryed的生命周期哪个更早?
开始源码分析
我们构建ViewModel, 需要传入Activity或者fragment。都会走到下面的方法, get的时候也是从ViewModelStore 去拿和获取
less
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
mViewModelStore = store;
}
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
if (mFactory instanceof OnRequeryFactory) {
((OnRequeryFactory) mFactory).onRequery(viewModel);
}
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) mFactory).create(key, modelClass);
} else {
viewModel = mFactory.create(modelClass);
}
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
所以从ViewModel的构建,我们知道是ViewModelStore进行维护了ViewModel的生命周期
ViewModelStore的管理
ViewModelStore的管理,需要实现ViewModelStoreOwner 接口,我们代码中主要 ComponentActivity 和 Fragment 实现了该接口,这里源码分析以ComponentActivity 分析
less
public ComponentActivity() {
//...
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
// Clear out the available context
mContextAwareHelper.clearAvailableContext();
// And clear the ViewModelStore
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
//...
}
在ComponentActivity 的构造方法的时候,我们发现Activty#getViewModelStore 会在lifecycleOwner#on_Destory的时候调用 clear方法,进入调用ViewModel#onClear方法,完成ViewModel的清理(tips: 这里有如果是配置变化引起的Activty的重建,并不会调用clear方法)
所以这个问题变成了Lifecycle#on_destory 事件回调和Activty#onDestory的时机问题
Lifecycle#on_destory 回调时机?
lifecycle的onEvent 主要是LifecycleRegistry
less
public class LifecycleRegistry extends Lifecycle {
public void setCurrentState(@NonNull State state) {
enforceMainThreadIfNeeded("setCurrentState");
moveToState(state);
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState()); //这个地方去回调所有的Observer
}
}
我在外面查了半天,外面查了半天,都没有找到 setCurrentState 和 handleLifecycleEvent 调用的地方。直到我看到这个代码
less
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
ReportFragment.injectIfNeededIn(this);
....
}
scss
public class ReportFragment extends android.app.Fragment {
private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
LifecycleCallbacks.registerIn(activity);
}
// Prior to API 29 and to maintain compatibility with older versions of
// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
// need to support activities that don't extend from FragmentActivity from support lib),
// use a framework fragment to get the correct timing of Lifecycle events
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();
}
}
@SuppressWarnings("deprecation")
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);
}
}
}
static ReportFragment get(Activity activity) {
return (ReportFragment) activity.getFragmentManager().findFragmentByTag(
REPORT_FRAGMENT_TAG);
}
private ActivityInitializationListener mProcessListener;
private void dispatchCreate(ActivityInitializationListener listener) {
if (listener != null) {
listener.onCreate();
}
}
private void dispatchStart(ActivityInitializationListener listener) {
if (listener != null) {
listener.onStart();
}
}
private void dispatchResume(ActivityInitializationListener listener) {
if (listener != null) {
listener.onResume();
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
// just want to be sure that we won't leak reference to an activity
mProcessListener = null;
}
}
利用了 Fragment 的生命周期回调,去监听 Activity 的生命周期,从而把生命周期事件(onStart/onStop/onResume...)转发给 Lifecycle → LiveData → LifecycleObserver。
这样好处:
- 关注点分离:Activity 专注于业务逻辑,生命周期管理交给专门组件
- 可测试性:Lifecycle 逻辑可以独立测试
- 一致性:所有 Activity 都有统一的生命周期管理方式
好的,这个问题就变成了Fragment#onDestory 和 Activity#onDestory的生命周期的问题
Fragment#onDestory的回调
Activity 中的 Fragment的生命周期回调,是受 FragmentController 控制的,我们可以看到这个代码performDestroy
scss
final void performDestroy() {
dispatchActivityPreDestroyed();
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy(); //Fragment 执行onDestory方法
onDestroy(); //activity的 onDestroy方法
EventLogTags.writeWmOnDestroyCalled(mIdent, getComponentName().getClassName(),
"performDestroy");
mFragments.doLoaderDestroy();
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
dispatchActivityPostDestroyed();
}
从这里可以得出问题结论,fragment#onDestroy 会在 Activity#onDestroy方法之前执行
Activity#performDestroy
activity#performDestroy 是哪里调过来的,其实我们知道activity的生命周期都是AMS跨进程调用ApplicationThread, 然后 ApplicationThread 通过H handler 执行 activity的生命周期方法。 所以我们应该可以从ActivityThread类中找到对应的代码。 下面贴出对应的代码作证一下
arduino
class H extends Handler{
....
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
...
break;
}
class TransactionExecutor{
...
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
....
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
...
}
}
}
class ActivityThread{
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
....
mInstrumentation.callActivityOnDestroy(r.activity);
}
}
class Instrumentation{
public void callActivityOnDestroy(Activity activity) {
activity.performDestroy(); //真正调用地方
}
}
总结整理一下
- AMS 发送 Activity#onDestroy → ApplicationThread →ActivityThread
- Activity#performDestroy()
- performDestroy 方法中,先让Fragment执行onDestroy, 然后执行自己的onDestroy方法
- Activity的lifecycle 的 Event的事件实现原理是,依赖Fragment的onDestroy声明周期
- ViewModelStore 接收到Actvity#lifecycle#onDestroy 调用ViewModel的cleared 方法
上面问题答案呼之欲出: ViewModel的cleared 是先于 Activity#onDestroy