上篇文章如何绑定页面生命周期(一)-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 浅析中关于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;
}
}
复制代码
具体工程代码可以从这里获取:CustomAACLifecycleDemo
结束
至此,关于AAC如何绑定页面生命周期的原理讲解结束。在上一篇文章如何绑定页面生命周期(一)-Glide实现,介绍了Glide绑定生命周期的原理。两种绑定页面生命周期的方式,大家可以对比着看,相信肯定会对绑定页面生命周期有更加深入的了解。