Lifecycle
Lifecycle 是 Android Architecture Components 的一个组件,用于将系统组件(Activity、Fragment 等等)的生命周期分离到 Lifecycle
类,Lifecycle
类允许其他类作为观察者,在外部观察系统组件生命周期的变化。Lifecycle 用起来很简单,首先声明一个 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
比如 LifecycleActivity
加入这么一行代码:
getLifecycle().addObserver(new LifecycleObserverDemo());
然后?然后就没然后了,运行起来可以看到 LifecycleActivity
的生命周期发生变化时,LifecycleObserverDemo
总能得到通知。而 LifecycleActivity
只有寥寥几行代码,并没有覆盖任何回调方法。那么 Lifecycle
是怎么做到的,是不是有点黑魔法的感觉?
注解的作用
首先从注解入手,可以在 build 目录下发现注解处理器为我们生成了 LifecycleObserverDemo_LifecycleAdapter
,不过这只是一个适配器,用于将生命周期事件派发到 LifecycleObserverDemo
对应的方法。
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;
}
}
如何传达 lifecycle 事件
Activity 不用写任何代码,那么 Lifecycle 是如何把 Activity 生命周期事件传递给 LifecycleObserver
?最终通过研读 Lifecycle 的代码,发现里面有个包可见的类 LifecycleDispatcher
,LifecycleDispatcher
是一个单例,在 LifecycleDispatcher#init(Context)
中,它通过 registerActivityLifecycleCallbacks
方法,向当前的 Application 注册一个 DispatcherActivityCallback
,但 Lifecycle 并没使用 ActivityLifecycleCallbacks
来监听并派发生命周期事件。
static void init(Context context){
...
((Application)context.getApplicationContext()).registerActivityLifecycleCallbacks(new LifecycleDispatcher.DispatcherActivityCallback());
...
}
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
...
if(manager.findFragmentByTag("android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag") == null) {
manager.beginTransaction().add(new ReportFragment(), "android.arch.lifecycle.LifecycleDispatcher.report_fragment_tag").commit();
manager.executePendingTransactions();
}
}
}
而是通过一个无 UI 的 Fragment,在 DispatcherActivityCallback#onActivityCreated
可以看到它在 Activity#onCreate
时,为 Activity 添加一个 ReportFragment
。最终由 ReportFragment
来监听各个生命周期事件,然后传递给 LifecycleRegistry
。
public class ReportFragment extends Fragment {
...
public void onPause() {
super.onPause();
dispatch(Event.ON_PAUSE);
}
...
private void dispatch(Event event) {
if(this.getActivity() instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner)this.getActivity()).getLifecycle().handleLifecycleEvent(event);
}
}
}
Activity 的生命周期事件都会派发到它的 Fragments,向 Activity 注册一个无 UI 的 Fragment 用于将各种 Activity 回调分离出来是个常用的做法,比如 RxPermissions 也是用这种方法来避免覆盖 Activity#onRequestPermissionsResult
或者引入 ShadowActivity 之类的 hack。
顺便一提 Lifecycle 文档提到:
ON_CREATE, ON_START, ON_RESUME events in this class are dispatched after the LifecycleOwner's related method returns. ON_PAUSE, ON_STOP, ON_DESTROY events in this class are dispatched before the LifecycleOwner's related method is called.
正好是 Fragment 生命周期回调的触发顺序。
终于 Activity 的生命周期变化是如何传递到 LifecycleObserver 有了清晰的图表:
LifecycleRuntimeTrojanProvider
还有一个问题, LifecycleDispatcher#init(Context)
并不是入口,它也需要被调用。那么他的调用者是谁?Google 这里的做法还是很巧妙的,如果把 apk 的 AndroidManifest.xml 提取出来,就会发现多了一个 ContentProvider 声明:
<provider
android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
android:authorities="${applicationId}.lifecycle-trojan"
android:exported="false"
android:multiprocess="true" />
LifecycleRuntimeTrojanProvider
运行时木马是什么鬼?实际上,它不是一个 ContentProvider,而是利用 ContentProvider 的特点在应用程序初始化时,向应用注入两行代码:
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
这里 ContentProvider 之于 Application 的作用就类似于无 UI Fragment 之于 Activity 一样,目的都是避免继承系统组件。关于 ContentProvider 的生命周期可以看 android - ContentProvider destruction/lifecycle - Stack Overflow,
其他 LifecycleOnwer
另外再提一下,Lifecycle 还提供了内置了另外三个 LifecycleOnwer:
- LifecycleFragment
- LifecycleService,ServiceLifecycleDispatcher 将事件派发重新推到主线程消息队列,用于保证确保回调在 Service 生命周期回调后再调用。
- ProcessLifecycleOwner,用于监听整个应用的前后台切换。也是利用 ActivityLifecycleCallback 监听每个 Activity 的生命周期,如果 onStop 事件后,没有监听到任意的 onStart 事件,那么 ProcessLifecycleOwner 就会认为整个应用切换到后台,同时留下一个标志。如果监听到 onStart 事件,同时检查有标志那么就会认为应用回到前台。