虐面试官系列Lifecyele 篇 -(1)基础知识
- 2020 年 2 月 16 日
- 笔记
又是很久很久没写文章了,最近打算写下Android的又一基础知识: Android 官方架构组件系列。打算把相关的知识点都整理写下,所以本系列的主体为Lifecycle.
虽然不敢保证每个人都看了之后都能完全融会贯通,但是我还是觉得看完虐一些普通面试官没啥任何问题(原谅我再一次捂脸吹牛逼)。



本系列适合三类读者:
- 完全没用过Lifecycle,但是听过,第一次接触的,想从浅入深的读者,我会有实际生活中的例子来让大家更容易掌握
- 稍微知道整个基础流程的,能大概讲个大概,但是深入就没有了解过的读者
- 自己也写过相关Lifecycle的文章,写了自认为所谓的《整个Lifecycle源码解析》的读者
也许有些人会说,那你凭啥说第三类读者还要读你的这篇Lifecycle文章,(当然有些作者是真的所有Lifecycle的完整的小细节都知道,只是没有写出来而已,那种可以忽视不看)
比如我问几个简单的Lifecycle面试问题:
- Lifecycle 我们知道很多文章都说你写了XXXLifecycleObserver后,编译后会自动生成XXXLifeObserver_LifecycleAdapter文件,但是我没引入
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
,不会自动生成这个辅助文件,这时候是怎么回调通知的。 - 为什么Lifecycle的State和Event是这么定义的,为什么State的值只有这么几个?
- LifecycleRegistry中管理我们观察者的队列 FastSafeIterableMap是我们平常使用的Map结构吗?如果不是那是什么,大概介绍下这种数据结构。
- 比如最后在sync()方法里面更新状态时候,下面这段代码部分看源码的作者应该不陌生,请看我在下面提的问题:
private void sync() { LifecycleOwner lifecycleOwner = mLifecycleOwner.get(); if (lifecycleOwner == null) { return; } while (!isSynced()) { mNewEventOccurred = false; /*'很多作者写这块介绍的时候就说简单的说拿队列头部的观察者的State和当前State比较, 如果小,就执行backwardPass方法, 如果大就执行forwardPass方法。' */ if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) { backwardPass(lifecycleOwner); /* '请问既然是执行backwardPass操作, 为什么不在这里直接添加return代码, 而执行完backwardPass后又去判断执行forwardPass了???' */ 'return;//为什么此处不加return,什么情况下会出错 ??' } Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest(); if (!mNewEventOccurred && newest != null && mState.compareTo(newest.getValue().mState) > 0) { forwardPass(lifecycleOwner); } } mNewEventOccurred = false; } /* '为什么backwardPass的时候,使用队列的头部状态值来比较,而forwardPass的时候是拿队列尾部的状态来比较?' '在具体执行forwardPass的时候,为什么使用的正序迭代器,而backwardPass的时候用的是倒序迭代器?' */ 复制代码
5.等等等等其他问题(太多了不想写了o(╥﹏╥)o)
正文:
1. 对比篇:

我们把以 房东 ——> 中介 ——> 购房者 三者来对比 Lifecycle ——> Lifecycle ——> LifecycleObserver。
具体的内容我们可以看脑图即可。
2. 基础篇:
关于基础篇,直接可以官网查看基础知识就行了:
2.1 集成方式一:
我就简单列出代码了:
** Activity (房东) **:
//'实现LifecycleOwner接口,等于门上贴了纸条,告诉人们,我有一个中介再帮我打理房子,有事找中介' public class MainActivity extends Activity implements LifecycleOwner { private LifecycleRegistry registry = new LifecycleRegistry(this); //'通过门口的号码,告诉你们,具体的中介是谁,直接找它吧' @NonNull @Override public Lifecycle getLifecycle() { return registry; } //'买家1' private LifeObserver observer1 = new LifeObserver(); //'买家2' private LifeObserver observer2 = new LifeObserver(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //'拿到了房屋中介对象,然后买家1到中介那边注册了' getLifecycle().addObserver(observer1); //'拿到了房屋中介对象,然后买家2到中介那边注册了' getLifecycle().addObserver(observer2); } //'房东的想法变了' @Override protected void onResume() { super.onResume(); //'中介马上把房东的新想法通知到各个买家' registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); } //'房东的想法变了' @Override protected void onPause() { super.onResume(); //'中介马上把房东的新想法通知到各个买家' registry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); } //'房东的想法变了' @Override protected void onStop() { super.onStop(); //'中介马上把房东的新想法通知到各个买家' registry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); } //'房屋买家类' class LifeObserver implements LifecycleObserver{ @OnLifecycleEvent(Lifecycle.Event.ON_ANY) public void AAAA(LifecycleOwner owner, Lifecycle.Event event){ //'买家收到中介的通知......' Log.v(TAG,"AAAA : " + event.name()); } } } 复制代码
没错,这个就是最基础的Lifecycle使用方式。是不是一下子就知道怎么使用了。
2.1 集成方式二:
很多人会说,我写的Activity怎么跟你的代码不一样,没有这么多杂七杂八的代码,比如:
public class Main2Activity extends AppCompatActivity { //'买家' private LifeObserver observer = new LifeObserver(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //'买家到中介处注册' getLifecycle().addObserver(observer); } } 复制代码
是不是少了很多,不需要各个生命周期去复写,然后发送事件,也不需要去实现LifecycleOwner接口,但是我们说了,你买房子既然走了这个流程,是不可能少任何东西了,只不过它内部帮我们把一些东西给提前写好了代码而已。
我们查看AppCompatActivity
的代码:
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback, SupportParentable, DelegateProvider { } public class FragmentActivity extends SupportActivity implements ViewModelStoreOwner, OnRequestPermissionsResultCallback, RequestPermissionsRequestCodeValidator { } //'我们的AppcompatActivity也等价于继承了SupportActivity' //'果然实现了LifecycleOwner接口' public class SupportActivity extends Activity implements LifecycleOwner, Component { //'果然,实例化了这个房屋中介对象' private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); //'也实现了这个方法,并且返回房屋中介对象' public Lifecycle getLifecycle() { return this.mLifecycleRegistry; } //'这个后面会具体给大家讲解,看过RxPermission源码的,应该一眼就知道' protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); } ...... ...... ...... } //'统一的中介分发房东信息类' public class ReportFragment extends Fragment { @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); } 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) { //'果然跟我们自己写的集成方式一相同,使用handleLifecycleEvent(event);去发送通知' ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); } } } } 复制代码
所以你们写的代码,本质上也就是跟我们刚写的一模一样。
2.1 集成方式三:
当然,如果你的support包比较老,可能默认的类似AppcompatActivity
都没有帮我们自动集成相关Lifecycle
代码,然后我们又不想写集成方式一那么多代码(每个生命周期事件都要复写,然后调用发送事件代码),想要实现类似集成方式二的使用方案,那怎么办呢???
implementation 'android.arch.lifecycle:extensions:1.1.1' 复制代码
我们只需要实现上面这个扩展包就可以了。
public class MainActivity extends Activity implements LifecycleOwner { private LifecycleRegistry registry = new LifecycleRegistry(this); @Override public Lifecycle getLifecycle() { return registry; } //'买家1' private LifeObserver observer1 = new LifeObserver(); //'买家2' private LifeObserver observer2 = new LifeObserver(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //'拿到了房屋中介对象,然后买家1到中介那边注册了' getLifecycle().addObserver(observer1); //'拿到了房屋中介对象,然后买家2到中介那边注册了' getLifecycle().addObserver(observer2); } } 复制代码
具体的原理我们后面会细细讲解,不用急。
集成方式一 代码量 > 集成方式三 代码量 > 集成方式二 代码量
所以我们可以根据不同情况来使用Lifecycle。
3. 使用场景 :
3.1 普通Activity、Fragment等生命周期监听
这个基本是包含了百分之90几的需求。
举例我们恰好用的是MVP模式,我现在要引入Lifecycle,这样V层销毁时候,我们的P层可以自动解绑(P层里面的网络请求自动解绑,P层自动与M层解绑,P层销毁,M层销毁等)
3.2 监听整个App
一个比较常见需求,比如我现在APP在运行,我点击了Home键,APP退到了后台,这时候我在退到后台后,会进行某一段代码,APP从后台又回来了,又要执行其他代码,这时候怎么写这个监听。
通常大部分人的写法是这样的:
public class DemoApplication extends Application { private int appCount; private boolean isRunInBackground; @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { appCount++; if (isRunInBackground) { //应用从后台回到前台 需要做的操作 isRunInBackground = false; //xxxxxxxxxxxxxx } } @Override public void onActivityStopped(Activity activity) { appCount--; if (appCount == 0) { //应用进入后台 需要做的操作 isRunInBackground = true; //xxxxxxxxxxxxxx } } ...... ...... ...... }); } } 复制代码
我们可以看到,我们监听了APP 里面所有的Activity的状态,如果所有的Activity都处于Stop状态,说明已经在后台了,如果有一个回到Start状态,且我们的boolean值变量也是true,则说明了回到了前台。
这个写法没啥问题,当然我们使用了Lifecycle后:
首先需要引进这个扩展包 implementation "android.arch.lifecycle:extensions:1.1.1"
ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifeObserver()); class LifeObserver extends LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) public void onForeground() { //应用进入前台 } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onBackground() { //应用进入后台 } } 复制代码
实际上真正的这个ProcessLifecycleOwner
用到的源码,也是跟我们registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks())
原理是一样的,只是他帮我们把这大批的代码给封装了而已。具体这块的源码分析,后面我会具体说明的。
3.3 配合LiveData,消息总线
Android消息总线的演进之路:用LiveDataBus替代RxBus、EventBus
3.4 其他
结语
本文我们可以学会基本的使用方式,通过房东-中介-购房者,能更好的理解。