Android Jetpack Components of Lifecycle 学习笔记
Android Jetpack Components of Lifecycle 学习笔记
Android Jetpack Components of LiveData 学习笔记
Android Jetpack Components of ViewModel 学习笔记
都说天下文章一大抄。不过我不担心,我从来不抄袭别人的见解。
也有人说博客、GibHub 上 90% 的内容都是重复的。这句话我赞同,但我不觉得这是件坏事。同一个事物,没有个人都应该有自己的辩证理解,否则就真的成为了天下文章一大抄了。
为了阐明我自己的理解、为了当做笔记便于日后回顾、也为了方便后来者少走弯路,我还是鼓起勇气写下后续的文章。尽管有那么多大神发布过类似的优秀文章。
说了一堆废话,今天我要聊的是 Lifecycle 组件。
组件地址:https://developer.android.google.cn/topic/libraries/architecture/lifecycle
你也可参考这位大佬的系列文章:https://www.jianshu.com/p/b1208012b268
插句废话:
访问 Android 官方网站 https://developer.android.com 需要的,否则无法访问;
访问 Android 中文网站 https://developer.android.google.cn 不需要。
貌似内容与 .com 网站一样,.google.cn 官方会定期更新的。
Lifecycle 环境配置:
1、如果是 sdk 小于 26 的版本,需要导入依赖包 android.arch.lifecycle
2、如果是 androidx 的环境,也需要导入依赖包,可参考 https://developer.android.google.cn/jetpack/androidx/releases/lifecycle#declaring_dependencies
3、除去以上情况之外,不需要任何导入,从 sdk 26 开始,系统内置了 Lifecycle 依赖包。
Lifecycle 官方原文定义:
Lifecycle-aware components perform actions in response to a change in the lifecycle status of another component, such as activities and fragments. These components help you produce better-organized, and often lighter-weight code, that is easier to maintain.
看过官方的解释,也看过很多优秀的博客,都说 Lifecycle 是可感知 Activity 和 Fragment 生命周期的组件。
来一个 Demo 对比说明问题,比喻一个工具类的注册于反注册,传统写法如下:
public class TestBus { private Activity mActivity; public void registerBusEvent(Activity activity) { this.mActivity = activity; // TODO: 2019/8/11 if } public void unRegister(Activity activity) { // TODO: 2019/8/11 if }}
public class LifecycleActivity extends AppCompatActivity { private TestBus mTestBus; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lifecycle); mTestBus = new TestBus(); mTestBus.registerBusEvent(this); } @Override protected void onDestroy() { super.onDestroy(); if (mTestBus != null) { mTestBus.unRegister(this); } }}
总结官方的解释和各路大神的见解,得出以上代码有如下缺点:
1、万一 mTestBus 对象忘记在 Activity 的 onDestroy() 方法中反注册了,会不会悲剧?
2、如果有更多的类似的功能类,都在 Activity 的 onDestroy() 方法中反注册,无效的代码量增大,是不是也是悲剧?
3、Activity 本是系统进程与应用程序进程之间进行生命周期回调的代理类,不应该写入过多的业务代码。
为了解决上面的问题,于是就有了 Lifecycle 组件,可感知 Activity 和 Fragment 的生命周期,类似反注册的代码可以完全放在自己的业务内处理。先上完整的 Demo,再说细节吧:
public class TestBus implements LifecycleObserver { private Activity mActivity; public void registerBusEvent(Activity activity) { this.mActivity = activity; // TODO: 2019/8/11 if } private void unRegister(Activity activity) { // TODO: 2019/8/11 if } // 需要监控 Activity onDestroy @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) public void onDestroy() { unRegister(mActivity); }}
public class LifecycleActivity extends AppCompatActivity { private TestBus mTestBus; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_lifecycle); mTestBus = new TestBus(); mTestBus.registerBusEvent(this); // 注册 lifecycle 观察者 getLifecycle().addObserver(mTestBus); }// @Override// protected void onDestroy() {// super.onDestroy();// if (mTestBus != null) {// mTestBus.unRegister(this);// }// }}
看完上面的代码后,你会发现 Activity 中明显的变化就是注释了 onDestroy() 方法。那么问题来了,不在 Activity 的 onDestroy() 方法中调用 TestBus 的反注册方法,TestBus 是怎么知道的?是不是 Lifecycle 把 Activity 做成事件源被观察者,然后让 TestBus 作为观察者,观察 Activity 的生命周期?那就来小撸一把源码吧。
首先看上面 Demo 中 Activity 的 onCreate() 方法中的那样代码,感觉像是注册观察者啊:
getLifecycle().addObserver(mTestBus);
你会发现 `getLifecycle()` 最终返回的是 `SupportActivity` 中的 `mLifecycleRegistry` 对象。
再深入分析 `LifecycleRegistry` 会发现,`Lifecycle` 是一个抽象类,里面提供了几个抽象方法,和两个枚举类。同时 `LifecycleRegistry` 继承了 `Lifecycle` 抽象类。
在`LifecycleRegistry` 的构造函数中,发现需要传入 `LifecycleOwner` 接口的实例,刚巧 `SupportActivity` 实现了此接口。
同时 `SupportActivity` 实现了接口的抽象方法 `getLifecycle()` ,返回的类型是必须是 `Lifecycle` 类型的。刚巧 `SupportActivity` 的 `getLifecycle()` 方法返回的是 `LifecycleRegistry` 类型。
我们继续分析代码 `getLifecycle().addObserver(mTestBus);` 像是往 `mLifecycleRegistry` 对象中添加观察者对象,需要的参数类型必须是 `LifecycleObserver`。这么巧,Demo 中的 `TestBus` 实现了接口 `LifecycleObserver`。
经过小段分析,我们理解为:
1、`SupportActivity` 内置了 `LifecycleRegistry` 对象,在构造 `LifecycleRegistry` 对象时,传入了自己的内存引用。
2、`LifecycleRegistry` 是 Activity 事件源的生命周期状态的管理类,在 `Activity` 初始化时创建。
3、`getLifecycle().addObserver(mTestBus);` 这行代码是注册观察者对象,当事件源生命周期变化时,会通知观察者。
到此,我们理解 `Lifecycle` 大部分原理,还剩下上例中 `TestBus` 中的几个注解的作用,和事件源的生命周期如何触发到 `TestBus` 的注解方法上的。
搜索 `Lifecycle.State` 枚举类,发现在 `LifecycleDispatcher.makeState()` 方法中使用到了。再在 `LifecycleDispatcher` 中继续追查 `Lifecycle.State` 的具体枚举,会发现在 `LifecycleDispatcher.onActivitySaveInstanceState()` 方法中用到了,同时在 `LifecycleDispatcher.DestructionReportFragment` 内部类中也大量使用到了。由此推测得出结论,当 `Activity` 和 `Fragment` 的生命周期发生变化时,会主动触发事件状态,最终都会调用到 `LifecycleRegistry.makeToState()` 方法中,再循环通知所有观察者对象的对应的方法中。
了解了上面的事件通知过程,那还有一步不知道。每当事件触发时,LifecycleRegistry 怎么知道观察者的哪个方法需要回调呢?
或者说上例中 TestBus 的 onDestroy() 方法如何被 LifecycleRegistry 回调呢?
我们观察注册观察者方法:
LifecycleRegistry.java@Overridepublic void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; // 注意看 ObserverWithState 的构造函数 ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); // ...}
ObserverWithState.javaObserverWithState(LifecycleObserver observer, State initialState) { // 注意看 Lifecycling.getCallback() 方法 mLifecycleObserver = Lifecycling.getCallback(observer); mState = initialState;}
Lifecycling.java@NonNullstatic 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); // ...}
Lifecycling.javaprivate static int getObserverConstructorType(Class<?> klass) { if (sCallbackCache.containsKey(klass)) { return sCallbackCache.get(klass); } // 注意看这个方法 int type = resolveObserverCallbackType(klass); sCallbackCache.put(klass, type); return type;}
Lifecycling.javaprivate static int resolveObserverCallbackType(Class<?> klass) { // anonymous class bug:35073837 // 此行代码 boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass); }
ClassesInfoCache.javaboolean hasLifecycleMethods(Class klass) { if (mHasLifecycleMethods.containsKey(klass)) { return mHasLifecycleMethods.get(klass); } Method[] methods = getDeclaredMethods(klass); for (Method method : methods) { OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class); if (annotation != null) { // Optimization for reflection, we know that this method is called // when there is no generated adapter. But there are methods with @OnLifecycleEvent // so we know that will use ReflectiveGenericLifecycleObserver, // so we createInfo in advance. // CreateInfo always initialize mHasLifecycleMethods for a class, so we don't do it // here. createInfo(klass, methods); return true; } } mHasLifecycleMethods.put(klass, false); return false;}
代码追查到这里,不想多说什么了。注解、反射!
源码分析到这里,已经很明了了。
Demo 地址:https://github.com/mengzhinan/Lifecycle_LiveData_ViewModel_demo
更多相关文章
- [置顶] Android SDK中的例子的源代码
- Android方法数超出限定的问题(multiDex,jumboMode)
- Android原生方法和Web JS互相调用-两种写法
- Android里的观察者模式应用
- android 访问网络不能在主线程中进行以及在线程中操作UI的解决方
- Android Studio——Android Studio更新升级方法
- SpannableString的使用方法
- Android文本输入框EditText属性和方法说明