上篇文章如何绑定页面生命周期(一)-Glide实现介绍了Glide实现生命周期感知的原理,这里咱们再介绍基于Android Architecture Components的Lifecycle实现页面生命周期感知。android
Lifecycle是Android Architecture Components(以后简称AAC)的一个组件,用于将系统组件(Activity、Fragment等等)的生命周期分离到Lifecycle类,Lifecycle容许其余类做为观察者,观察组件生命周期的变化。git
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");
}
}
复制代码
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感知生命周期的原理。github
经过在对指定activity注册无UI的Fragment,传递页面Activity生命周期到Fragment。而后经过Fragment绑定LifecycleRegistry,当Fragment的生命周期变化时,回调LifecycleRegistry中LifecycleObserver对象相应的生命周期回调方法。bash
下图是文章Android Architecture Component -- Lifecycle 浅析中关于Lifecycle生命周期传递的一幅图,我以为很清晰地展现了生命周期的传递过程。下面咱们跟着这幅图,来一步步看一下生命周期是如何传递的。app
如何在Activity上注册无UI的ReportFragment框架
首先看下LifecycleDispatcher初始化的过程:ide
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext()); // 监听整个应用先后台切换
复制代码
<provider
android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
android:authorities="${applicationId}.lifecycle-trojan"
android:exported="false"
android:multiprocess="true" />
复制代码
在这个LifecycleRuntimeTrojanProvider(低版本的AAC里,这个类叫ProcessLifecycleOwnerInitializer)的初始化方法中,实现了LifecycleDispatcher的相应初始化操做。函数
下面再来看一下LifecycleDispatcher的init方法:post
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
查看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
对象
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生命周期的感知。
Demo省略了注解相关步骤,须要观察者本身去实现一个ZRLifecycleObserver接口。虽然稍有不一样,可是不妨碍理解。
Demo的框架图以下所示:
使用的话也比较简单,主要进行如下一些设置。
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");
}
}
复制代码
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ZRLifecycleDispatcher.init(this);
}
}
复制代码
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绑定生命周期的原理。两种绑定页面生命周期的方式,你们能够对比着看,相信确定会对绑定页面生命周期有更加深刻的了解。