01 Lifecycle架構(gòu)組件原理解析

提綱
  • 什么是Lifecycle;
  • 如何使用Lifecycle觀察宿主狀態(tài);
  • Fragment是如何實現(xiàn)Lifecycle的;
  • Activity是如何實現(xiàn)Lifecycle的;
  • Lifecycle是如何分發(fā)宿主狀態(tài)。
什么是Lifecycle

Lifecycle是具備宿主生命周期感知能力的組件。它能持有組件(如Activity或Fragment)生命周期狀態(tài)的信息,并且允許其他觀察者監(jiān)聽宿主的狀態(tài)。它也是Jetpack組件庫的核心基礎(chǔ),包括我們就會講到的LiveData,ViewModel組件等也都是基于它來實現(xiàn)的。

再也不用手動分發(fā)宿主生命周期,再也不用手動反注冊了

Lifecycle的兩種寫法

Lifecycle有兩種實現(xiàn)方法,下面我們一一來介紹一下:
使用Lifecycle前需要先添加依賴:

 //通常情況下,只需要添加appcompat就可以了
api 'androidx.appcompat:appcompat:1.1.0'
 //如果想單獨使用,可引入下面這個依賴
api 'androidx.lifecycle:lifecycle-common:2.1.0'
LifecycleObserver配合注解:
//1. 自定義的LifecycleObserver觀察者,在對應(yīng)方法上用注解聲明想要觀  察的宿主的生命周期事件即可
class LocationObserver implements LifecycleObserver{
    //宿主執(zhí)行了onstart時,會分發(fā)該事件
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(@NotNull LifecycleOwner owner){
      //開啟定位
    }
  
  //宿主執(zhí)行了onstop時 會分發(fā)該事件
  @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
  void onStop(@NotNull LifecycleOwner owner){
     //停止定位
  }
 }

//2. 注冊觀察者,觀察宿主生命周期狀態(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寫法老師比較推薦第二種,因為第一種你雖然用注解很爽,但是如果沒有添加lifecycle-compiler這個注解處理器的話,運行時會使用反射的形式回調(diào)到對應(yīng)的方法上。

Fragment是如何實現(xiàn)Lifecycle的?

使用Fragment實現(xiàn)Lifecycle需要在各個生命周期方法內(nèi)里雍LifecycleRegistry分發(fā)相應(yīng)的事件給每個觀察者,以實現(xiàn)生命周期觀察的能力:

public class Fragment implements LifecycleOwner {
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
  @Override
  public Lifecycle getLifecycle() {  
      //復(fù)寫自LifecycleOwner,所以必須new LifecycleRegistry對象返回
      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è)計到三個分類,我們分別來捋一捋:

  • LifecycleOwner:我們的Activity/Fragment都實現(xiàn)了該接口,用以生命它是一個能夠提供生命周期事件的宿主。同時必須復(fù)寫getLifecycle()方法提供一個Lifecycle對象;
  • Lifecycle:是一個抽象類,里面定義了兩個枚舉State宿主的狀態(tài),Event需要分發(fā)的事件的類型;
  • LifecycleRegistry:是Lifecycle的唯一實現(xiàn)類,主要用來負(fù)責(zé)注冊O(shè)bserver,以及分發(fā)宿主狀態(tài)事件給它們。
Activity是如何實現(xiàn)Lifecycle的?

Activity實現(xiàn)Lifecycle需要借助于ReportFragment往Activity上添加一個fragment用以報告生命周期的變化。目的是為了兼容不是集成自AppCompactActivity的場景,同時也支持我們自定義LifecycleOwener的場景,注意了,這點面試會考?。?!

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上添加一個fragment,用以報告生命周期的變化
      //目的是為了兼顧不是繼承自AppCompactActivity的場景.
      ReportFragment.injectIfNeededIn(this); 
}
ReportFragment核心源碼

這里的實現(xiàn)其實跟Fragment中的源碼是一樣的,在各個生命周期方法內(nèi)利用LifecycleRegistry派發(fā)相應(yīng)的Lifecycle.Event事件給每個觀察者:

  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ā)事件的時候會涉及到兩個概念:

  • 宿主生命周期:就是我們爛熟于心的onCreate,onStart,onResume,onPause,onStop...;
  • 宿主的狀態(tài):這個不是很好理解,這個意思是指宿主執(zhí)行了上述方法后,它處于對應(yīng)周期的生命狀態(tài)。

從下面這張圖不難看出宿主生命周期與宿主狀態(tài)的對應(yīng)關(guān)系分裂為onCreate-Created、onStart-Started、onResume-Resumed、onPause-Started、onStop-Created、onDestroy-Destroyed,這里不用全部記住有個印象即可。

添加observer時,完整的生命周期事件分發(fā)

基于Lifecycle的特性我們在任意生命周期方法內(nèi)注冊觀察者都能接受到完整的生命周期事件,比如在onResume中注冊一個觀察者,它會依次收到:

LifecycleEvent.onCreate -> LifecycleEvent.onStart -> LifecycleEvent.onResume
添加Observer時完整的生命周期事件分發(fā)源碼分析

這一點需要掌握,面試中是肯定會考察的。但是如果沒有看過源碼是回答不上來的:

public void addObserver(@NonNull LifecycleObserver observer) {
        //添加新的Observer時,會首先根據(jù)宿主的狀態(tài)計算出它的初始狀態(tài),只要不是在onDestroy中注冊的,它的初始狀態(tài)都是INITIALIZED
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        //接著會把observer包裝成ObserverWithState,這個類主要是包含了觀察者及其狀態(tài)。每個事件都會經(jīng)由這個對象類轉(zhuǎn)發(fā),這個類后面會來分析
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        //添加到集合,如果之前已經(jīng)添加過了,則return
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        if (previous != null) {
            return;
        }
        
        State targetState = calculateTargetState(observer);
        //這里的while循環(huán),是實現(xiàn)上圖狀態(tài)同步與事件分發(fā)的主要邏輯
        //拿觀察者的狀態(tài)和宿主當(dāng)前狀態(tài)做比較,如果小于0,說明兩者狀態(tài)還沒有對齊。
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            //接著就會分發(fā)一次相應(yīng)的事件,于此同時statefulObserver的mState對象也會被升級
            //假設(shè)是在宿主的onresume方法內(nèi)注冊的該觀察者
            //第一次:分發(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));
            //再一次計算觀察者應(yīng)該到達(dá)的狀態(tài),在下一輪循環(huán)中和宿主狀態(tài)在做比較,知道兩者狀態(tài)對齊,退出循環(huán)。
            targetState = calculateTargetState(observer);
        }
    }
宿主生命周期變化后相應(yīng)事件的分發(fā)

這一點了解即可,面試中也不會考這一部分的內(nèi)容:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event){      
        //宿主的每個生命周期的變化都會分發(fā)一個對應(yīng)的Lifecycle.Event,走到這里
        //此時會根據(jù)需要分發(fā)的事件反推出 宿主當(dāng)前的狀態(tài)
        State next = getStateAfter(event);
        // moveToState方法只是將傳入的宿主新的state和前持有宿主狀態(tài)作比對,然后保存一下。
        moveToState(next);
}
//如果宿主狀態(tài)有變動,則調(diào)用sync方法來完成事件的分發(fā)和觀察者狀態(tài)的同步
private void sync() {
        while (!isSynced()) {
        //如果宿主當(dāng)前轉(zhuǎn)態(tài) 小于 mObserverMap集合中最先添加的那個觀察者的狀態(tài)
        //則說明宿主可能發(fā)生了狀態(tài)回退,比如當(dāng)前是RESUMED狀態(tài),執(zhí)行了onPause則回退到STARTED狀態(tài)
        //此時調(diào)用backwardPass把集合中的每個一觀察者分發(fā)一個on_pause事件,并同步它的狀態(tài)。
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
        //如果宿主當(dāng)前轉(zhuǎn)態(tài) 大于 mObserverMap集合中最先添加的那個觀察者的狀態(tài)
        //則說明宿主可能發(fā)生了狀態(tài)前進(jìn),比如當(dāng)前是STARTED狀態(tài),執(zhí)行了onResume則前進(jìn)到RESUMED狀態(tài)
        //此時調(diào)用forwardPass把集合中的每個一觀察者分發(fā)一個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)部類

把傳入的LifecycleObserver適配成LifecycleEventObserver,目的是為了統(tǒng)一事件的分發(fā)形式。

持有觀察者的狀態(tài),方便與宿主狀態(tài)做比對同步:

static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;
        ObserverWithState(LifecycleObserver observer, State initialState) {
            //把傳入的LifecycleObserver適配成LifecycleEventObserver,目的是為了統(tǒng)一事件的分發(fā)形式
            //因為我們前面提到觀察者有三種類型,每種類型接收事件的形式并不一樣,如果在分發(fā)的時候不統(tǒng)一事件分發(fā)的形式,將會變得很麻煩
            //至于是如何適配轉(zhuǎn)換的,由于不是本文重點,所以不再詳細(xì)展開
            //但核心思想這里說明一下,同學(xué)們自行看下就能明白
            //它會判斷傳入的observer是前面提到的那一種類型,進(jìn)而轉(zhuǎn)換成對應(yīng)的適配器類,適配器類會對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ā)的事件類型反推出該觀察者的狀態(tài),這樣的好處是事件 &  狀態(tài) 一一對應(yīng),不會出現(xiàn)跳躍。但閱讀上可能會稍微有點繞
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            //把事件分發(fā)給被包裝的對象,完成本次流程。
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }
    }
總結(jié)

本篇從 三種用法+分發(fā)原理+面試考點 三個維度展開對Lifecycle組件的介紹,現(xiàn)在相信同學(xué)們已經(jīng)掌握了Lifecycle的核心了。Lifecycle組件是Jetpack組件庫的核心,一旦跟宿主生命周期掛鉤,那可以做很多文章,后面講到的LiveData、ViewModel都是基于它來實現(xiàn)的。

  • 本篇最后給同學(xué)們留下一個小作業(yè),基于Lifecycle實現(xiàn)APP前后臺切換事件觀察的能力。這個作業(yè)可以讓同學(xué)們加深對Lifecycle組件的理解
作業(yè):基于Lifecycle實現(xiàn)APP前后臺切換事件觀察的能力
class AppLifecycleOwner implements LifecycleOwner{
  LifecycleRegistry registry = new LifecycleRegistry(this)
  @override
  Lifecycle getLifecycle(){
    return  registry
  }

  void init(Application application){
    //利用application的  ActivityLifecycleCallbacks 去監(jiān)聽每一個  Activity的onstart,onStop事件。
    //計算出可見的Activity數(shù)量,從而計算出當(dāng)前處于前臺還是后臺。然后分發(fā)  給每個觀察者
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容