ViewModel#onCleared的实现原理

开局一个问题

请问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 接口,我们代码中主要 ComponentActivityFragment 实现了该接口,这里源码分析以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
    }
}

我在外面查了半天,外面查了半天,都没有找到 setCurrentStatehandleLifecycleEvent 调用的地方。直到我看到这个代码

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(); //真正调用地方
  }
}

总结整理一下

  1. AMS 发送 Activity#onDestroy → ApplicationThread →ActivityThread
  2. Activity#performDestroy()
  3. performDestroy 方法中,先让Fragment执行onDestroy, 然后执行自己的onDestroy方法
  4. Activity的lifecycle 的 Event的事件实现原理是,依赖Fragment的onDestroy声明周期
  5. ViewModelStore 接收到Actvity#lifecycle#onDestroy 调用ViewModel的cleared 方法

上面问题答案呼之欲出: ViewModel的cleared 是先于 Activity#onDestroy

相关推荐
laocooon523857886几秒前
C#二次开发中简单块的定义与应用
android·数据库·c#
似霰25 分钟前
传统 Hal 开发笔记5 —— 添加硬件访问服务
android·framework·hal
恋猫de小郭28 分钟前
Android 宣布 Runtime 编译速度史诗级提升:在编译时间上优化了 18%
android·前端·flutter
csj5042 分钟前
安卓基础之《(4)—Activity组件》
android
游戏开发爱好者81 小时前
H5 混合应用加密 Web 资源暴露到 IPA 层防护的完整技术方案
android·前端·ios·小程序·uni-app·iphone·webview
2501_915106321 小时前
最新版本iOS系统设备管理功能全面指南
android·macos·ios·小程序·uni-app·cocoa·iphone
走在路上的菜鸟2 小时前
Android学Dart学习笔记第十四节 库和导库
android·笔记·学习·flutter
姜西西_2 小时前
自动化测试框架pytest之fixture
android·java·pytest
尐葮阿譽2 小时前
Ubuntu 25.10 安装 Waydroid 安卓模拟器
android·ubuntu·安卓模拟器·waydroid
_李小白2 小时前
【Android FrameWork】实战:跟踪Android APP Surface创建流程
android