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
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 注意看 ObserverWithState 的构造函数
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// ...
}
ObserverWithState.java
ObserverWithState(LifecycleObserver observer, State initialState) {
// 注意看 Lifecycling.getCallback() 方法
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
Lifecycling.java
@NonNull
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);
// ...
}
Lifecycling.java
private static int getObserverConstructorType(Class<?> klass) {
if (sCallbackCache.containsKey(klass)) {
return sCallbackCache.get(klass);
}
// 注意看这个方法
int type = resolveObserverCallbackType(klass);
sCallbackCache.put(klass, type);
return type;
}
Lifecycling.java
private static int resolveObserverCallbackType(Class<?> klass) {
// anonymous class bug:35073837
// 此行代码
boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
}
ClassesInfoCache.java
boolean 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