上篇文章如何绑定页面生命周期(一)-Glide 实现介绍了 Glide 实现生命周期感知的原理, 这里我们再介绍基于 Android Architecture Components 的 Lifecycle 实现页面生命周期感知.
Lifecycle 是 Android Architecture Components(之后简称 AAC)的一个组件, 用于将系统组件 (Activity,Fragment 等等) 的生命周期分离到 Lifecycle 类, Lifecycle 允许其他类作为观察者, 观察组件生命周期的变化.
基于 AAC 实现组件生命周期观察实践
控件实现 LifecycleObserver 接口, 内部通过 @OnLifecycleEvent 注解声明生命周期事件
- public class LifecycleObserverDemo implements LifecycleObserver {
- @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
- void onAny(LifecycleOwner owner, Lifecycle.Event event) {
- System.out.println("onAny:" + event.name());
- }
- @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
- void onCreate() {
- System.out.println("onCreate");
- }
- @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
- void onDestroy() {
- System.out.println("onDestroy");
- }
- }
复制代码
在 LifecycleRegistryOwner, 比如在实现了 LifecycleRegistryOwner 接口的 Activity 中. 定义 LifecycleRegistry 实例, 并将控件 lifecycleRegistry 实例中的监听集合中.
- public class MainActivity extends AppCompatActivity implements LifecycleRegistryOwner {
- // 定义 LifecycleRegistry 实例
- private LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 加入监听集合
- getLifecycle().addObserver(new LifecycleObserverDemo());
- }
- @Override
- public LifecycleRegistry getLifecycle() {
- return lifecycleRegistry;
- }
- }
复制代码
只需要如上两步, 当 Activity 页面生命周期发生变化时, 都会通知到 LifecycleObserverDemo. 同样, 本文以 Activity 为例, 介绍 Lifecycle 感知生命周期的原理.
生命周期绑定实现原理
实现原理简介
通过在对指定 activity 注册无 UI 的 Fragment, 传递页面 Activity 生命周期到 Fragment. 然后通过 Fragment 绑定 LifecycleRegistry, 当 Fragment 的生命周期变化时, 回调 LifecycleRegistry 中 LifecycleObserver 对象相应的生命周期回调方法.
如何传递生命周期
下图是文章 Android Architecture Component -- Lifecycle 浅析 https://www.jianshu.com/p/bd800c5dae30 中关于 Lifecycle 生命周期传递的一幅图, 我觉得很清晰地展示了生命周期的传递过程. 下面我们跟着这幅图, 来一步步看一下生命周期是如何传递的.
如何在 Activity 上注册无 UI 的 ReportFragment
首先看下 LifecycleDispatcher 初始化的过程:
利用 ContentProvider 的特点在应用程序初始化时, 向其注入两行代码:
- LifecycleDispatcher.init(getContext());
- ProcessLifecycleOwner.init(getContext()); // 监听整个应用前后台切换
复制代码
这个 ContentProvider 从哪里来? 查看 apk 中的 AndroidManifest.xml 文件, 发现多了一个 ContentProvider 声明:
- <provider
- android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
- android:authorities="${applicationId}.lifecycle-trojan"
- android:exported="false"
- android:multiprocess="true" />
复制代码
在这个 LifecycleRuntimeTrojanProvider(低版本的 AAC 里, 这个类叫 ProcessLifecycleOwnerInitializer)的初始化方法中, 实现了 LifecycleDispatcher 的相应初始化操作.
下面再来看一下 LifecycleDispatcher 的 init 方法:
- static void init(Context context) {
- if (sInitialized.getAndSet(true)) {
- return;
- }
- ((Application) context.getApplicationContext())
- .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
- }
复制代码
在 LifecycleDispatcher#init(Context) 中, 它通过 registerActivityLifecycleCallbacks 方法, 向当前的 Application 注册一个 DispatcherActivityCallback. 但 Lifecycle 并没使用 ActivityLifecycleCallbacks 来监听并派发生命周期事件. 而是通过一个无 UI 的 Fragment, 在 DispatcherActivityCallback#onActivityCreated 可以看到它在 Activity#onCreate 时, 为 Activity 添加一个 ReportFragment. 最终由 ReportFragment 来监听各个生命周期事件, 然后传递给 LifecycleRegistry.
无 UI 的 Fragment 与 LifecycleRegistry 建立联系
查看 ReportFragment 的生命周期回调方法:
- @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;
- }
复制代码
回调生命周期方法时, 会调用 dispatch(Lifecycle.Event event)方法. 看下 dispatch(Lifecycle.Event event)方法的源码:
- private void dispatch(Lifecycle.Event event) {
- Activity activity = getActivity();
- 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);
- }
- }
- }
复制代码
这里会通过 ReportFragment 注册的 Activity 的 getLifecycle()方法获取 LifecycleRegistry, 然后调用 LifecycleRegistry 的 handleLifecycleEvent(@NonNull Lifecycle.Event event)处理传递的生命周期 Event.
_LifecycleAdapter 如何与 LifecycleRegistry 建立联系
在 LifecycleRegistry 中, 定义了如下的 map:
- private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
- new FastSafeIterableMap<>();
复制代码
当我们在页面 Activity 中将观察者加入集合时, 加入的就是上面定义的 mObserverMap.ObserverWithState 对象构造函数初始化时, 通过 Lifecycling.getCallback(observer)方法返回 GenericLifecycleObserver 对象, 实际上就是_LifecycleAdapter 对象. 因为_LifecycleAdapter 实现了 GenericLifecycleObserver.
- static GenericLifecycleObserver getCallback(Object object) {
- if (object instanceof FullLifecycleObserver) {
- return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
- }
- if (object instanceof GenericLifecycleObserver) {
- return (GenericLifecycleObserver) object;
- }
- final Class<?> klass = object.getClass();
- int type = getObserverConstructorType(klass);
- if (type == GENERATED_CALLBACK) {
- List<Constructor<? extends GeneratedAdapter>> constructors =
- sClassToAdapters.get(klass);
- if (constructors.size() == 1) {
- GeneratedAdapter generatedAdapter = createGeneratedAdapter(
- constructors.get(0), object);
- return new SingleGeneratedAdapterObserver(generatedAdapter);
- }
- GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
- for (int i = 0; i < constructors.size(); i++) {
- adapters[i] = createGeneratedAdapter(constructors.get(i), object);
- }
- return new CompositeGeneratedAdaptersObserver(adapters);
- }
- return new ReflectiveGenericLifecycleObserver(object);
- }
复制代码
基于注解生成了_LifecycleAdapter 的 class, 通过反射生成_LifecycleAdapter 对象
_LifecycleAdapter 回调生命周期方法, 继续传递生命周期给最终的观察者
LifecycleRegistry 和_LifecycleAdapter 建立联系后, 生命周期会通过调用 ObserverWithState 的 dispatchEvent 方法:
- void dispatchEvent(LifecycleOwner owner, Event event) {
- State newState = getStateAfter(event);
- mState = min(mState, newState);
- mLifecycleObserver.onStateChanged(owner, event);
- mState = newState;
- }
复制代码
最终, 会调用 mLifecycleObserver, 即我们前面返回的_LifecycleAdapter 的 onStateChanged 方法. 下面看下_LifecycleAdapter 的实现:
- public class LifecycleObserverDemo_LifecycleAdapter implements GenericLifecycleObserver {
- final LifecycleObserverDemo mReceiver;
- LifecycleObserverDemo_LifecycleAdapter(LifecycleObserverDemo receiver) {
- this.mReceiver = receiver;
- }
- @Override
- public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
- mReceiver.onAny(owner,event);
- if (event == Lifecycle.Event.ON_CREATE) {
- mReceiver.onCreate();
- }
- if (event == Lifecycle.Event.ON_START) {
- mReceiver.onStart();
- }
- if (event == Lifecycle.Event.ON_PAUSE) {
- mReceiver.onPause();
- }
- if (event == Lifecycle.Event.ON_DESTROY) {
- mReceiver.onDestroy();
- }
- }
- public Object getReceiver() {
- return mReceiver;
- }
- }
复制代码
上面的类, 可以在 build 目录下找到. 这是注解处理器为我们生成了 LifecycleObserverDemo_LifecycleAdapter, 不过这只是一个适配器, 用于将生命周期事件派发到 LifecycleObserverDemo 对应的方法. 至此, LifecycleObserverDemo 实现了对页面 Activity 生命周期的感知.
核心类介绍
LifecycleObserver: 接口, 标记一个类是可观察的, 基于注解实现相应回调方法
Lifecycle: 抽象类, 拥有 android 生命周期
LifecycleRegistry: 继承 Lifecycle, 可以处理多 LifecycleObserver
LifecycleOwner: 接口, 持有一个 android lifecycle
LifecycleRegistryOwner: 接口, 继承 LifecycleOwner, 返回 LifecycleRegistry
LifecycleDispatcher: 在 Application 中 hook, 观察 activity 的生命周期并分发
LifecycleRuntimeTrojanProvider:LifecycleDispatcher 等初始化
生命周期管理框架实践
Demo 省略了注解相关步骤, 需要观察者自己去实现一个 ZRLifecycleObserver 接口. 虽然稍有不同, 但是不妨碍理解.
Demo 的框架图如下所示:
使用的话也比较简单, 主要进行以下一些设置.
观察者实现 ZRLifecycleObserver 接口
- public class MyView extends View implements ZRLifecycleObserver {
- public MyView(Context context) {
- this(context, null);
- }
- public MyView(Context context,
- @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
- @Override
- public void onCreate() {
- System.out.println("MyView onCreate");
- }
- @Override
- public void onStart() {
- System.out.println("MyView onStart");
- }
- @Override
- public void onResume() {
- System.out.println("MyView onResume");
- }
- @Override
- public void onPause() {
- System.out.println("MyView onPause");
- }
- @Override
- public void onStop() {
- System.out.println("MyView onStop");
- }
- @Override
- public void onDestroy() {
- System.out.println("MyView onDestroy");
- }
- @Override
- public void onRestart() {
- System.out.println("MyView onRestart");
- }
- }
复制代码
应用启动时初始化 ZRLifecycleDispatcher
- public class MyApplication extends Application {
- @Override
- public void onCreate() {
- super.onCreate();
- ZRLifecycleDispatcher.init(this);
- }
- }
复制代码
被观察页面实现 ZRLifecycleRegistryOwner, 并将要要观察此页面生命周期的观察者对象加入集合
- public class MainActivity extends Activity implements ZRLifecycleRegistryOwner {
- private ZRLifecycleRegistry lifecycleRegistry = new ZRLifecycleRegistry(this);
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- MyView myView = findViewById(R.id.view_test);
- getLifecycle().addObserver(myView);
- }
- @Override
- public ZRLifecycleRegistry getLifecycle() {
- return lifecycleRegistry;
- }
- }
复制代码
具体工程代码可以从这里获取: https://github.com/yushiwo/CustomAACLifecycleDemo
结束
至此, 关于 AAC 如何绑定页面生命周期的原理讲解结束. 在上一篇文章如何绑定页面生命周期(一)-Glide 实现, 介绍了 Glide 绑定生命周期的原理. 两种绑定页面生命周期的方式, 大家可以对比着看, 相信肯定会对绑定页面生命周期有更加深入的了解.
参考
Android Architecture Component -- Lifecycle 浅析 https://www.jianshu.com/p/bd800c5dae30
来源: https://juejin.im/post/5b5c9e23e51d451912533ea8