提綱
- 什么是Lifecycle贷祈;
- 如何使用Lifecycle觀察宿主狀態(tài)嫂丙;
- Fragment是如何實(shí)現(xiàn)Lifecycle的绍傲;
- Activity是如何實(shí)現(xiàn)Lifecycle的幻枉;
- Lifecycle是如何分發(fā)宿主狀態(tài)碰声。
什么是Lifecycle
Lifecycle是具備宿主生命周期感知能力的組件。它能持有組件(如Activity或Fragment)生命周期狀態(tài)的信息熬甫,并且允許其他觀察者監(jiān)聽(tīng)宿主的狀態(tài)胰挑。它也是Jetpack組件庫(kù)的核心基礎(chǔ),包括我們就會(huì)講到的LiveData椿肩,ViewModel組件等也都是基于它來(lái)實(shí)現(xiàn)的瞻颂。
再也不用手動(dòng)分發(fā)宿主生命周期,再也不用手動(dòng)反注冊(cè)了
Lifecycle的兩種寫(xiě)法
Lifecycle有兩種實(shí)現(xiàn)方法郑象,下面我們一一來(lái)介紹一下:
使用Lifecycle前需要先添加依賴(lài):
//通常情況下贡这,只需要添加appcompat就可以了
api 'androidx.appcompat:appcompat:1.1.0'
//如果想單獨(dú)使用,可引入下面這個(gè)依賴(lài)
api 'androidx.lifecycle:lifecycle-common:2.1.0'
LifecycleObserver配合注解:
//1. 自定義的LifecycleObserver觀察者厂榛,在對(duì)應(yīng)方法上用注解聲明想要觀 察的宿主的生命周期事件即可
class LocationObserver implements LifecycleObserver{
//宿主執(zhí)行了onstart時(shí)盖矫,會(huì)分發(fā)該事件
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(@NotNull LifecycleOwner owner){
//開(kāi)啟定位
}
//宿主執(zhí)行了onstop時(shí) 會(huì)分發(fā)該事件
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(@NotNull LifecycleOwner owner){
//停止定位
}
}
//2. 注冊(cè)觀察者,觀察宿主生命周期狀態(tài)變化
class MyFragment extends Fragment{
public void onCreate(Bundle bundle){
LocationObserver observer =new LocationObserver()
getLifecycle().addObserver(observer);
}
}
LifecycleEventObserver宿主生命周期事件封裝成Lifecycle.Event
//1.源碼
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
}
//2.用法
class LocationObserver extends LifecycleEventObserver{
@override
void onStateChanged(LifecycleOwner source, Lifecycle.Event event){
//需要自行判斷l(xiāng)ife-event是onstart, 還是onstop
}
}
上面的這兩種Lifecycle寫(xiě)法老師比較推薦第二種丽惭,因?yàn)榈谝环N你雖然用注解很爽,但是如果沒(méi)有添加lifecycle-compiler這個(gè)注解處理器的話(huà)辈双,運(yùn)行時(shí)會(huì)使用反射的形式回調(diào)到對(duì)應(yīng)的方法上责掏。
Fragment是如何實(shí)現(xiàn)Lifecycle的?
使用Fragment實(shí)現(xiàn)Lifecycle需要在各個(gè)生命周期方法內(nèi)里雍LifecycleRegistry分發(fā)相應(yīng)的事件給每個(gè)觀察者湃望,以實(shí)現(xiàn)生命周期觀察的能力:
public class Fragment implements LifecycleOwner {
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
public Lifecycle getLifecycle() {
//復(fù)寫(xiě)自L(fǎng)ifecycleOwner,所以必須new LifecycleRegistry對(duì)象返回
return mLifecycleRegistry;
}
void performCreate(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
.....
void performResume(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
}
LifecycleOwner拷橘、Lifecycle、LifecycleRegistry的關(guān)系
事件在分發(fā)宿主生命期事件的流程中設(shè)計(jì)到三個(gè)分類(lèi)喜爷,我們分別來(lái)捋一捋:
- LifecycleOwner:我們的Activity/Fragment都實(shí)現(xiàn)了該接口,用以生命它是一個(gè)能夠提供生命周期事件的宿主萄唇。同時(shí)必須復(fù)寫(xiě)getLifecycle()方法提供一個(gè)Lifecycle對(duì)象檩帐;
- Lifecycle:是一個(gè)抽象類(lèi),里面定義了兩個(gè)枚舉State宿主的狀態(tài)另萤,Event需要分發(fā)的事件的類(lèi)型湃密;
- LifecycleRegistry:是Lifecycle的唯一實(shí)現(xiàn)類(lèi),主要用來(lái)負(fù)責(zé)注冊(cè)O(shè)bserver四敞,以及分發(fā)宿主狀態(tài)事件給它們泛源。
Activity是如何實(shí)現(xiàn)Lifecycle的?
Activity實(shí)現(xiàn)Lifecycle需要借助于ReportFragment往Activity上添加一個(gè)fragment用以報(bào)告生命周期的變化忿危。目的是為了兼容不是集成自AppCompactActivity的場(chǎng)景达箍,同時(shí)也支持我們自定義LifecycleOwener的場(chǎng)景,注意了铺厨,這點(diǎn)面試會(huì)考6忻怠!解滓!赃磨。
public class ComponentActivity extends Activity implements LifecycleOwner{
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
protected void onCreate(Bundle bundle) {
super.onCreate(savedInstanceState);
//往Activity上添加一個(gè)fragment,用以報(bào)告生命周期的變化
//目的是為了兼顧不是繼承自AppCompactActivity的場(chǎng)景.
ReportFragment.injectIfNeededIn(this);
}
ReportFragment核心源碼
這里的實(shí)現(xiàn)其實(shí)跟Fragment中的源碼是一樣的,在各個(gè)生命周期方法內(nèi)利用LifecycleRegistry派發(fā)相應(yīng)的Lifecycle.Event事件給每個(gè)觀察者:
public class ReportFragment extends Fragment{
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
}
private void dispatch(Lifecycle.Event event) {
Lifecycle lifecycle = activity.getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
宿主生命周期與宿主狀態(tài)模型圖
LifecycleRegistry在分發(fā)事件的時(shí)候會(huì)涉及到兩個(gè)概念:
- 宿主生命周期:就是我們爛熟于心的onCreate,onStart,onResume,onPause,onStop...洼裤;
- 宿主的狀態(tài):這個(gè)不是很好理解邻辉,這個(gè)意思是指宿主執(zhí)行了上述方法后,它處于對(duì)應(yīng)周期的生命狀態(tài)腮鞍。
從下面這張圖不難看出宿主生命周期與宿主狀態(tài)的對(duì)應(yīng)關(guān)系分裂為onCreate-Created值骇、onStart-Started、onResume-Resumed移国、onPause-Started雷客、onStop-Created、onDestroy-Destroyed桥狡,這里不用全部記住有個(gè)印象即可搅裙。
添加observer時(shí)皱卓,完整的生命周期事件分發(fā)
基于Lifecycle的特性我們?cè)谌我馍芷诜椒▋?nèi)注冊(cè)觀察者都能接受到完整的生命周期事件,比如在onResume中注冊(cè)一個(gè)觀察者部逮,它會(huì)依次收到:
LifecycleEvent.onCreate -> LifecycleEvent.onStart -> LifecycleEvent.onResume
添加Observer時(shí)完整的生命周期事件分發(fā)源碼分析
這一點(diǎn)需要掌握娜汁,面試中是肯定會(huì)考察的。但是如果沒(méi)有看過(guò)源碼是回答不上來(lái)的:
public void addObserver(@NonNull LifecycleObserver observer) {
//添加新的Observer時(shí)兄朋,會(huì)首先根據(jù)宿主的狀態(tài)計(jì)算出它的初始狀態(tài)掐禁,只要不是在onDestroy中注冊(cè)的,它的初始狀態(tài)都是INITIALIZED
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//接著會(huì)把observer包裝成ObserverWithState颅和,這個(gè)類(lèi)主要是包含了觀察者及其狀態(tài)傅事。每個(gè)事件都會(huì)經(jīng)由這個(gè)對(duì)象類(lèi)轉(zhuǎn)發(fā),這個(gè)類(lèi)后面會(huì)來(lái)分析
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//添加到集合,如果之前已經(jīng)添加過(guò)了峡扩,則return
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
State targetState = calculateTargetState(observer);
//這里的while循環(huán)蹭越,是實(shí)現(xiàn)上圖狀態(tài)同步與事件分發(fā)的主要邏輯
//拿觀察者的狀態(tài)和宿主當(dāng)前狀態(tài)做比較,如果小于0教届,說(shuō)明兩者狀態(tài)還沒(méi)有對(duì)齊响鹃。
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
//接著就會(huì)分發(fā)一次相應(yīng)的事件,于此同時(shí)statefulObserver的mState對(duì)象也會(huì)被升級(jí)
//假設(shè)是在宿主的onresume方法內(nèi)注冊(cè)的該觀察者
//第一次:分發(fā)on_Create事件案训,觀察者狀態(tài)INIT->CREATED
//第二次:分發(fā)on_Start事件买置,觀察者狀態(tài)CREATED->STARTED
//第三次:分發(fā)on_Resume事件,觀察者狀態(tài)STARTED->RESUMED
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
//再一次計(jì)算觀察者應(yīng)該到達(dá)的狀態(tài)强霎,在下一輪循環(huán)中和宿主狀態(tài)在做比較忿项,知道兩者狀態(tài)對(duì)齊,退出循環(huán)城舞。
targetState = calculateTargetState(observer);
}
}
宿主生命周期變化后相應(yīng)事件的分發(fā)
這一點(diǎn)了解即可倦卖,面試中也不會(huì)考這一部分的內(nèi)容:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event){
//宿主的每個(gè)生命周期的變化都會(huì)分發(fā)一個(gè)對(duì)應(yīng)的Lifecycle.Event,走到這里
//此時(shí)會(huì)根據(jù)需要分發(fā)的事件反推出 宿主當(dāng)前的狀態(tài)
State next = getStateAfter(event);
// moveToState方法只是將傳入的宿主新的state和前持有宿主狀態(tài)作比對(duì)椿争,然后保存一下怕膛。
moveToState(next);
}
//如果宿主狀態(tài)有變動(dòng),則調(diào)用sync方法來(lái)完成事件的分發(fā)和觀察者狀態(tài)的同步
private void sync() {
while (!isSynced()) {
//如果宿主當(dāng)前轉(zhuǎn)態(tài) 小于 mObserverMap集合中最先添加的那個(gè)觀察者的狀態(tài)
//則說(shuō)明宿主可能發(fā)生了狀態(tài)回退秦踪,比如當(dāng)前是RESUMED狀態(tài)褐捻,執(zhí)行了onPause則回退到STARTED狀態(tài)
//此時(shí)調(diào)用backwardPass把集合中的每個(gè)一觀察者分發(fā)一個(gè)on_pause事件,并同步它的狀態(tài)椅邓。
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
//如果宿主當(dāng)前轉(zhuǎn)態(tài) 大于 mObserverMap集合中最先添加的那個(gè)觀察者的狀態(tài)
//則說(shuō)明宿主可能發(fā)生了狀態(tài)前進(jìn)柠逞,比如當(dāng)前是STARTED狀態(tài),執(zhí)行了onResume則前進(jìn)到RESUMED狀態(tài)
//此時(shí)調(diào)用forwardPass把集合中的每個(gè)一觀察者分發(fā)一個(gè)on_resume事件景馁,并同步它的狀態(tài)板壮。
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
}
ObserverWithState:持有觀察者及其狀態(tài)的內(nèi)部類(lèi)
把傳入的LifecycleObserver適配成LifecycleEventObserver,目的是為了統(tǒng)一事件的分發(fā)形式合住。
持有觀察者的狀態(tài)绰精,方便與宿主狀態(tài)做比對(duì)同步:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//把傳入的LifecycleObserver適配成LifecycleEventObserver撒璧,目的是為了統(tǒng)一事件的分發(fā)形式
//因?yàn)槲覀兦懊嫣岬接^察者有三種類(lèi)型,每種類(lèi)型接收事件的形式并不一樣,如果在分發(fā)的時(shí)候不統(tǒng)一事件分發(fā)的形式笨使,將會(huì)變得很麻煩
//至于是如何適配轉(zhuǎn)換的卿樱,由于不是本文重點(diǎn),所以不再詳細(xì)展開(kāi)
//但核心思想這里說(shuō)明一下硫椰,同學(xué)們自行看下就能明白
//它會(huì)判斷傳入的observer是前面提到的那一種類(lèi)型繁调,進(jìn)而轉(zhuǎn)換成對(duì)應(yīng)的適配器類(lèi),適配器類(lèi)會(huì)對(duì)onStateChanged方法進(jìn)行適配靶草,并以相應(yīng)的方式(反射蹄胰、中轉(zhuǎn)、)把事件轉(zhuǎn)發(fā)到我們的observer上
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
//再一次根據(jù)需要分發(fā)的事件類(lèi)型反推出該觀察者的狀態(tài),這樣的好處是事件 & 狀態(tài) 一一對(duì)應(yīng)奕翔,不會(huì)出現(xiàn)跳躍裕寨。但閱讀上可能會(huì)稍微有點(diǎn)繞
State newState = getStateAfter(event);
mState = min(mState, newState);
//把事件分發(fā)給被包裝的對(duì)象,完成本次流程糠悯。
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
總結(jié)
本篇從 三種用法+分發(fā)原理+面試考點(diǎn) 三個(gè)維度展開(kāi)對(duì)Lifecycle組件的介紹,現(xiàn)在相信同學(xué)們已經(jīng)掌握了Lifecycle的核心了妻往。Lifecycle組件是Jetpack組件庫(kù)的核心互艾,一旦跟宿主生命周期掛鉤,那可以做很多文章讯泣,后面講到的LiveData纫普、ViewModel都是基于它來(lái)實(shí)現(xiàn)的。
- 本篇最后給同學(xué)們留下一個(gè)小作業(yè)好渠,基于Lifecycle實(shí)現(xiàn)APP前后臺(tái)切換事件觀察的能力昨稼。這個(gè)作業(yè)可以讓同學(xué)們加深對(duì)Lifecycle組件的理解
作業(yè):基于Lifecycle實(shí)現(xiàn)APP前后臺(tái)切換事件觀察的能力
class AppLifecycleOwner implements LifecycleOwner{
LifecycleRegistry registry = new LifecycleRegistry(this)
@override
Lifecycle getLifecycle(){
return registry
}
void init(Application application){
//利用application的 ActivityLifecycleCallbacks 去監(jiān)聽(tīng)每一個(gè) Activity的onstart,onStop事件。
//計(jì)算出可見(jiàn)的Activity數(shù)量拳锚,從而計(jì)算出當(dāng)前處于前臺(tái)還是后臺(tái)假栓。然后分發(fā) 給每個(gè)觀察者
}
}