天天看點

Android architecture components學習筆記1-Lifecycle源碼分析

    • AAC簡介
      • –使用ViewModel代替了Present。
      • –VIew和ViewModel單向依賴。
    • AAC元件簡介
      • –LifeCycle
      • –LiveData
      • –ViewModel
    • LifeCycle簡介
    • 如何讓自己建立的對象感覺Activity/fragment生命周期
    • Lifecycle的例子
    • Lifecycle生命周期
      • –Event 事件
      • –State 狀态
    • Lifecycle主要類
      • LifecycleObserver
      • LifecycleOwner
      • Lifecycle
      • LifecycleRegistry
    • Lifecycle流程分析
      • Fragment通知LifecycleRegistry
      • Activity通知LifecycleRegistry
      • ReportFragment傳遞生命周期事件
      • 将LifecycleObserver添加到Lifecycle中
      • LifecycleRegistry分發生命周期事件到LifecycleObserver中
      • sync方法
    • Lifecycle設計思路借鑒

我們知道在安卓的開發中,出現過很多的架構,從最開始的直接4大元件開撸的類mvc,到後來的mvp,mvvm。有鑒于此,google也終于在2017年的IO開發大會上推出了Android Architecture Components(AAC)來幫助Android開發者建構更好的app架構。

AAC簡介

關于AAC架構,沒有比官方提供的整體架構圖更能說明了,我們先看官方架構圖。

Android architecture components學習筆記1-Lifecycle源碼分析

可以看到,AAC實際上是一個mvvm架構,由activity,fragment充當view,ViewModel充當控制層,Repository充當資料源。那麼從圖上看,AAC架構和我們常用的mvp架構的最大差別在哪裡呢?個人認為最主要的差別有2點。

–使用ViewModel代替了Present。

–VIew和ViewModel單向依賴。

我們都知道,在mvp中,view和Present會互相持有對方的引用,已達到View和present互動的目的,但是在AAC中,隻有View持有ViewModel的引用,而ViewModel并不持有View的引用,這是如何做到的呢?這就是圖中的LiveData的功勞啦,我們之後介紹。

AAC元件簡介

–LifeCycle

生命周期管理(Lifecycles)元件,幫助開發者建立 “可感覺生命周期的” 元件,讓其自己管理自己的生命周期,進而減少記憶體洩露和崩潰的可能性。生命周期庫是其他架構元件(如 LiveData)的基礎。

android.arch.lifecycle 包提供了類和接口允許你建構生命周期感覺(lifecycle-aware)的元件——可以基于目前activity或fragment生命周期自動調節它們的行為的元件。

–LiveData

LiveData 是一款基于觀察者模式的可感覺生命周期的核心元件。LiveData 為界面代碼 (Observer)的監視對象 (Observable),當 LiveData 所持有的資料改變時,它會通知相應的界面代碼進行更新。同時,LiveData 持有界面代碼 Lifecycle 的引用,這意味着它會在界面代碼(LifecycleOwner)的生命周期處于 started 或 resumed 時作出相應更新,而在 LifecycleOwner 被銷毀時停止更新。通過 LiveData,開發者可以友善地建構安全性更高、性能更好的高響應度使用者界面。

–ViewModel

ViewModel 将視圖的資料和邏輯從具有生命周期特性的實體(如 Activity 和 Fragment)中剝離開來。直到關聯的 Activity 或 Fragment 完全銷毀時,ViewModel 才會随之消失,也就是說,即使在旋轉螢幕導緻 Fragment 被重新建立等事件中,視圖資料依舊會被保留。ViewModels 不僅消除了常見的生命周期問題,而且可以幫助建構更為子產品化、更友善測試的使用者界面。

上面三個元件的介紹來自官方文檔,初看可能不明覺厲,不過不要緊,下面我們将分别進行介紹。

LifeCycle簡介

LifeCycle可以說是AAC架構的一個核心元件,它的作用是可以讓我們建立具有生命周期的對象,這是什麼意思呢?大家都知道,我們平常使用的Activity,fragment等,都是具有生命周期的,而且它們的生命周期都是由系統進行管理的,我們app無法對其進行控制,而是隻能收到生命周期變化的回調,比如onCreate,onStart等方法。作為一個開發者,我們必須遵守這些生命周期的規則,否則就可能出現應用奔潰或者記憶體洩漏的情況。而我們的LifeCycle包就是為了讓我們自己建立的對象也能感受到android元件生命周期而誕生的。參考官方介紹和教程

https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html

如何讓自己建立的對象感覺Activity/fragment生命周期

設想一下,如果讓我們自己設計,我們要如何讓自建對象感覺activity或者fragment的生命周期呢?我覺得這個問題并不困難,在mvp的某一種實作中,我們為了讓Present能夠感覺到Activity的生命周期,就采用了下面的方法來解決這個問題。示例代碼如下:

public class Present {
    public void onCreate(){
    }

    public void onStart(){
    }

    public void onStop(){
    }

    public void onDestroy(){   
    }
}
           

我們先在Present中增加需要的各個回調方法,之後Activity持有Present的引用,并在Activity的生命周期方法中,調用Present的方法,這樣我們的Present也有了生命周期。

public class MainActivity extends AppCompatActivity {

    private Present present = new Present();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        present.onCreate();
    }

    @Override
    protected void onStart() {
        super.onStart();
        present.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        present.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        present.onDestroy();
    }
}
           

這個例子看起來也很好的實作了需求,但是毫無擴充性,比如我還有另一個對象B也需要聲明周期或者其他Activity中的對象C也需要聲明周期呢,難道我們要把這段代碼寫很多遍麼,另外如果我們現在需要Activity目前的狀态,比如是否執行過onResume,或者是否執行過onStop應該怎麼做呢,為了滿足這些需求,我們決定把這個例子改良一下。

首先,我們把Activity的生命周期事件抽象成一個接口,其他的類繼承該接口就可以接收到Activity的生命周期事件。

public interface ILifecycle {
    void onCreate();
    void onStart();
    void onResume();
    void onPause();
    void onStop();
    void onDestroy();
}
           

其次我們抽象出一個BaseActivity,用它來管理所有需要生命周期事件的對象,并分發生命周期事件。同時記錄Activity的生命周期狀态。 可以看到我們采用了很經典的觀察者模式向生命周期對象分發Activity的生命周期事件,代碼比較好看懂。

public class BaseActivity extends AppCompatActivity{

    private List<ILifecycle> lifes = new ArrayList<>();
    protected String mLifeCycle = "INIT";

    public String getmLifeCycle() {
        return mLifeCycle;
    }

    protected void addLifecycle(ILifecycle cycle){
        if(!lifes.contains(cycle)){
            lifes.add(cycle);
        }
    }

    protected void removeLifecycle(ILifecycle cycle){
        if(lifes.contains(cycle)){
            lifes.remove(cycle);
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        for(ILifecycle cycle:lifes){
            cycle.onCreate();
        }
        mLifeCycle = "CREATE";
    }

    @Override
    protected void onStart() {
        super.onStart();
        for(ILifecycle cycle:lifes){
            cycle.onStart();
        }
        mLifeCycle = "START";
    }

    @Override
    protected void onResume() {
        super.onResume();
        for(ILifecycle cycle:lifes){
            cycle.onResume();
        }
        mLifeCycle = "RESUME";
    }

    @Override
    protected void onPause() {
        super.onPause();
        for(ILifecycle cycle:lifes){
            cycle.onPause();
        }
        mLifeCycle = "PAUSE";
    }

    @Override
    protected void onStop() {
        super.onStop();
        for(ILifecycle cycle:lifes){
            cycle.onStop();
        }
        mLifeCycle = "STOP";
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        for(ILifecycle cycle:lifes){
            cycle.onDestroy();
        }
        mLifeCycle = "DESTROY";
    }
}
           

最後,讓我們的Present實作ILifecycle接口,MainActivity繼承自BaseActivity基類,并在onCreate方法中将Prenset加入觀察,即完成了Present對象對生命周期事件的監聽。

public class Present implements ILifecycle{
}
           
public class MainActivity extends BaseActivity {
    private Present present = new Present();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        addLifecycle(present);
        super.onCreate(savedInstanceState);
    }
}
           

Lifecycle的例子

說了這麼多,終于到了我們今天的主角,我們先直接來看看,使用Lifecycle的話,我們之前的例子要怎麼寫。首先,我們實作LifecycleObserver接口,使用注解标明我們需要的生命周期事件,這裡我們選擇接受onCreate事件,當Activity的onCreate被調用時,我們的Present的onCreate也會被調用。

public class Present implements LifecycleObserver{
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(){
    }
}
           

然後,我們繼承自AppCompatActivity,并在onCreate中完成注冊即可,是不是超級簡單。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLifecycle().addObserver(new Present());
    }
}
           

Lifecycle生命周期

lifecycle使用了2個枚舉來跟蹤它所關聯的元件的生命周期

–Event 事件

從元件或者Lifecycle類分發出來的生命周期,它們和Activity/Fragment生命周期的事件一一對應。(ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY)

–State 狀态

目前元件的生命周期狀态(INITIALIZED,DESTROYED,CREATED,STARTED,RESUMED)

它們的轉換關系見下面的官方說明

Android architecture components學習筆記1-Lifecycle源碼分析

Lifecycle主要類

Lifecycle的實作不算複雜,主要的類如下圖所示

Android architecture components學習筆記1-Lifecycle源碼分析

可以看到,主要有3大核心子產品。LifecycleObserver及其子類為被觀察者,負責接收生命周期事件,我們自定義的接收器就需要繼承自LifecycleObserver接口;Lifecycle為被被觀察者,負責從Activity,fragment接收生命周期事件,并分發到觀察者中;LifecycleOwner的職責很簡單,僅僅是提供了Lifecycle對象,我們使用的Support包下的Fragment和AppCompatActivity都實作了該接口。

LifecycleObserver

我們的Present對象實作了LifecycleObserver接口,隻有實作該接口的對象才能夠收到生命周期事件,我們來看看該接口究竟是怎麼回事呢?

/**
 * Marks a class as a LifecycleObserver. It does not have any methods, instead, relies on
 * {@link OnLifecycleEvent} annotated methods.
 */
public interface LifecycleObserver {
}
           

出乎意料的是,該接口并沒有任何内容,源碼注釋告訴我們,需要監聽哪個生命周期,使用OnLifecycleEvent注解标明即可。我們來看看OnLifecycleEvent注解的内容。

@SuppressWarnings("unused")
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnLifecycleEvent {
    Lifecycle.Event value();
}
           

可以看到,該注解是一個運作時注解,可以使用在方法體上,傳回的Lifecycle.Event對象就是我們上一節提到的Event事件。那麼為什麼使用該注解辨別的方法就會被調用呢,我們之後分析。

LifecycleOwner

LifecycleOwner是一個接口,它隻有一個方法getLifecycle用于擷取Lifecycle對象

public interface LifecycleOwner {
    Lifecycle getLifecycle();
}
           

我們來看看有哪些類實作了該接口以友善我們使用Lifecycle,可以看到,我們的support包下的Fragment直接實作了該接口,并提供了一個Lifecycle的具體實作類LifecycleRegistry。

public class Fragment implements LifecycleOwner{
    //Lifecycle的實作類LifecycleRegistry
    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        //覆寫LifecycleOwner接口的getLifecycle方法
        //并傳回LifecycleRegistry
        return mLifecycleRegistry;
    }
}
           

繼續檢視我們發現support包下的SupportActivity實作了該接口,同樣提供了一個LifecycleRegistry。而我們發現AppCompatActivity最終也繼承自SupportActivity,是以在我們平時的開發中,隻要繼承自Support包的Fragment和AppCompatActivity就可以友善的使用Lifecycle,而不用額外的繼承自某個特定的基類Activity或者fragment,是不是很友善。

public class SupportActivity extends Activity implements LifecycleOwner{
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}
           

Lifecycle

該類是一個抽象類,扮演了一個被觀察者的角色,從Activity/fragment中接收事件,并分發到觀察者LifecycleObserver,我們來看具體代碼。

public abstract class Lifecycle {
    //添加觀察者
    public abstract void addObserver(LifecycleObserver observer);
    //移除觀察者
    public abstract void removeObserver(LifecycleObserver observer);
    //擷取目前的State
    public abstract State getCurrentState();
    //Lifecycle生命周期的Event事件
    public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }
    //Lifecycle生命周期的State狀态
    public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
    }
}
           

該類是一個抽象類,其中的addObserver,removeObserver方法是觀察者模式當中典型的添加,删除觀察者方法。而其内部類Event和State就是我們之前說過的Lifecycle的Event事件和State狀态。

LifecycleRegistry

該類為Lifecycle的實作類,添加,移除觀察者,以及分發生命周期事件到LifecycleObserver中都是由該類實作的,我們之後會進行重點分析。

Lifecycle流程分析

我們從以下幾個方面來分析Lifecycle的工作過程。

1,fragment/activity生命周期事件如何通知LifecycleRegistry

2,如果添加和移除LifecycleObserver到LifecycleRegistry中?

3,LifecycleRegitstry如何通知LifecycleObserver?

Fragment通知LifecycleRegistry

public class Fragment implements LifecycleOwner{
    //建立LifecycleRegistry對象,該對象就是LifecycleOwner的實作類。
    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

     void performCreate(Bundle savedInstanceState) {
        //...無關代碼
        //先執行onCreate
        onCreate(savedInstanceState);
        //分發ON_CREATE這個Event給LifecycleRegistry
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

     void performDestroy() {
        //...無關代碼
        //先分發ON_DESTROY事件
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        //後執行onDestroy方法
        onDestroy();
    }
    //省略onStart,onResume,onPause,onStop等事件的分發,和上面一緻。
}
           

可以看到,Fragment生命周期通知Lifecycle的過程非常直接,fragment中建立了LifecycleRegistry對象,在fragment的生命周期中直接調用了LifecycleRegistry的handleLifecycleEvent方法,這樣就将生命周期通知到了Lifecycle。

Activity通知LifecycleRegistry

看完上面Fragment生命周期分發的過程,大家可能覺得Activity的過程都不用看了吧,畢竟照着上面來一遍,生命周期事件也就分發出去了,如果你是這麼想的,那可就錯了,我們來看代碼。

public class SupportActivity extends Activity implements LifecycleOwner {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在本Activity添加一個ReportFragment,使用該Fragment來跟蹤
        //Activity的生命周期
        ReportFragment.injectIfNeededIn(this);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        //将Lifecycle的狀态修改為CREATE
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
        super.onSaveInstanceState(outState);
    }
}
           

可以看到,google竟然不按套路出牌,雖然建立了LifecycleRegistry,但是在Activity的生命周期方法中使用它傳遞事件,那麼生命周期事件如何建立了,答案就是onCreate中的ReportFragment,google使用它來感覺Activity的生命周期,并傳遞生命周期事件到Lifecycle中,我們來看看ReportFragment吧。

ReportFragment傳遞生命周期事件

public class ReportFragment extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
        FragmentManager manager = activity.getFragmentManager();
        //建立自身并添加到宿主Activity中
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            manager.executePendingTransactions();
        }
    }

    static ReportFragment get(Activity activity) {
        //擷取自身的執行個體
        return (ReportFragment) activity.getFragmentManager().findFragmentByTag(
                REPORT_FRAGMENT_TAG);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //分發ON_CREATE事件
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //分發ON_DESTROY事件
        dispatch(Lifecycle.Event.ON_DESTROY);
    }
    //...其他生命周期事件的分發省略

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        //如果宿主Activity繼承了LifecycleOwner,則分發生命周期事件
        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
}
           

可以看到,我們在Activity的onCreate方法中,将ReportFragment添加進來,之後該Fragment就具有了和宿主Activity一樣的生命周期,我們在ReportFragment的生命周期中分發事件到Lifecycle中即可。

那麼問題就來了,我們直接在SupportActivity的生命周期方法中,向lifecycle傳遞事件一樣可以達到目的啊,為啥還搞出了一個ReportFragment,感覺很多餘啊,google為何要這麼做呢?個人推測這個問題的原因和Lifecycle的曆史實作有關,我們之後再解釋。

将LifecycleObserver添加到Lifecycle中

前面我們介紹了,Lifecycle是基于觀察者模式工作的,那麼我們是什麼時候将觀察者注冊到Lifecycle中的呢?沒錯,就是通過下面這個簡單的語句,我們就注冊了觀察者。

getLifecycle().addObserver(new Present());
           

通過前面的分析,我們知道,getLifecycle方法擷取到的為LifecycleRegistry的執行個體,我們先來看看LifecycleRegistry中2個很重要的成員變量。

public class LifecycleRegistry extends Lifecycle{
     //Lifecycle自定義的資料結構,我們可以看成HashMap,支援周遊時添加,删除元素。
     private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();
     //目前的生命周期狀态
     private State mState;
}
           

我們來梳理一下,首先在LifecycleRegistry類中,會使用一個類似LinkedHashMap的結構來儲存所有的被觀察者,已確定生命周期發生變化時,能夠通知LifecycleObserver。

這裡有一個注釋說明,說的是我們如果按照ob1,ob2的順序添加了觀察者,那麼ob1的狀态将會大于或等于ob2的狀态,這個會有什麼影響呢?影響就是啟動時,ob1的ON_CREATE,ON_START,ON_RESUME事件會先于Ob2。而停止時,ob2的ON_PAUSE,ON_STOP事件先于ob1。

它的鍵是我們的觀察者LifecycleObserver對象,值是ObserverWithState對象,這個對象其實隻是一個簡單的對Observer和State的封裝,我們看一下他的實作。

static class ObserverWithState {
    //儲存目前Observer的狀态
    State mState;
    //源Observer的包裝類
    GenericLifecycleObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        //生成一個原Observer的包裝類
        mLifecycleObserver = Lifecycling.getCallback(observer);
        mState = initialState;
    }
    //該方法将生命周期事件分發到LifecycleObserver中
    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        //調用包裝類的onStateChanged方法,傳遞生命周期事件到Observer中
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}
           

原來ObserverWithState類的實作很簡單,主要就是儲存了目前Observer類的狀态State,并且使用Lifecycling類的getCallback方法傳回了一個LifecycleObserver的真正實作類,該實作類就是之前類圖中的ReflectiveGenericLifecycleObserver。

該類的實作原理我們大緻說一下,在建立的時候,使用反射掃描我們傳入的Observer對象中包含了OnLifecycleEvent注解的方法,将掃描到的方法緩存下來,并在調用GenericLifecycleObserver類的onStateChanged方法時,找到真正的生命周期回調方法并調用。詳細代碼我們這裡就不分析了。

我們繼續看關鍵的addObserver方法

@Override
public void addObserver(LifecycleObserver observer) {
//計算初始狀态,如果目前Lifecycle狀态不為DESTROYED,我們就設定為初始狀态
  State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
  ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//如果Map中存在observer這個key,我們傳回它原來對應的值,否則将該鍵值對加入map
  ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//一個observer不能多次加入到同一個Lifecycle中,是以我們這裡判斷如果它已經加入
//過了,則直接傳回,不進行處理。
  if (previous != null) {
      return;
  }
//判斷該添加是否可重入,這裡和多線程添加Observer有關,正常情況下,我們在主線程中
//添加Observer,該标志永遠為false
  boolean isReentrance = mAddingObserverCounter !=  || mHandlingEvent;
//計算目前Lifecycle的狀态
  State targetState = calculateTargetState(observer);
  mAddingObserverCounter++;
//如果我們新添加的觀察者的狀态小于目前狀态,則我們将它遷移到目前狀态
//例如目前狀态為RESUMED,則Observer将收到ONCREATE ONSTART ONRESUME事件
  while ((statefulObserver.mState.compareTo(targetState) < 
          && mObserverMap.contains(observer))) {
      //調用ObserverWithState對象的dispatchEvent方法,向真正的Observer發送生命周期事件
      statefulObserver.dispatchEvent(mLifecycleOwner, upEvent(statefulObserver.mState));
      //重新計算目前狀态
      targetState = calculateTargetState(observer);
  }
  //該方法我們之後分析
  if (!isReentrance) {
      sync();
  }
  mAddingObserverCounter--;
}
           

可以看到,該方法大體分為4個步驟,詳細流程圖如下:

Android architecture components學習筆記1-Lifecycle源碼分析

1,計算Observer的初始狀态,并建立包裝類ObserverWithState。

2,如果全局Map中已經存在該Observer了,直接傳回,如果不存在,則加入map中。

3,将Observer的目前狀态和Lifecycle的狀态進行比較,如果Lifecycle的狀态較大,則循環遷徙Observer的狀态為和Lifecycle的狀态一緻。

4,調用sync方法同步所有的Observer對象的生命周期狀态,該方法我們之後會進行詳細分析

針對第三點舉個例子,例如我們在Activity的onResume中添加Observer,則由于Lifecycle的狀态為RESUMED,而我們添加的Observer的狀态為INIT,那麼Observer的狀态将依次變為CREATED,STARTED,RESUMED.并受到ON_CREATE ONSTART ONRESUME事件。

LifecycleRegistry分發生命周期事件到LifecycleObserver中

之前我們已經了解到Activity,Fragment通過LifecycleRegistry類的handleLifecycleEvent方法将生命周期事件傳遞到Lifecycle中,我們接下來就分析該方法,看看Lifecycle怎樣将該事件分發到所有的觀察者Observer中。

public void handleLifecycleEvent(Lifecycle.Event event) {
    //1,根據目前事件,擷取該事件發生後的狀态
    mState = getStateAfter(event);
    //2,這個判斷個人了解隻有多線程下執行本方法或者addObserver
    //方法才會發生。由于我們基本不會這麼用,是以可以跳過。
    if (mHandlingEvent || mAddingObserverCounter != ) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        return;
    }
    mHandlingEvent = true;
    //3,執行關鍵的同步sync方法
    sync();
    mHandlingEvent = false;
}
           

該方法的實作比較簡單,第一步就是根據目前收到的生命周期事件,判斷我們之後應處于的狀态,我們來看一下getStateAfter的源代碼

static State getStateAfter(Event event) {
    switch (event) {
        case ON_CREATE:
        case ON_STOP:
            return CREATED;
        case ON_START:
        case ON_PAUSE:
            return STARTED;
        case ON_RESUME:
            return RESUMED;
        case ON_DESTROY:
            return DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException("Unexpected event value " + event);
}
           

該方法的實作比較簡單,對照之前的事件狀态轉換圖,可謂一目了然。

我們回到handleLifecycleEvent方法,該方法的第二步是判斷mHandlingEvent 為真或者mAddingObserverCounter不為0,就傳回,不執行之後的操作。這2個判斷個人了解是為了在addObserver和本方法可能執行在其他線程服務的,因為如果大家都執行在主線程的話,這些判斷根本就不會起作用,由于handleLifecycleEvent方法在前面的實作中,一定執行在主線程,是以隻有addObserver方法執行在子線程時,這個判斷才會起作用。我們暫時忽略這種情況,繼續分析。

sync方法

該方法的第三步執行了sync方法,同步所有的觀察者狀态,我們來分析sync方法。

private void sync() {
    //判斷是否同步完成,如果未完成,則同步直到完成為止。
    while (!isSynced()) {
        mNewEventOccurred = false;
        //之前我們說過,排在全局map第一位的狀态是最大的,如果我們目前lifecycle
        //狀态比它小,那麼我們需要回退某些Observer的狀态到mState
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < ) {
            backwardPass();
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        //之前我們說過,排在全局map最後的狀态是最小的,如果我們目前lifecycle
        //狀态比它大,那麼我們需要前進某些Observer的狀态到mState
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > ) {
            forwardPass();
        }
    }
    mNewEventOccurred = false;
}
           

可以看到,sync方法也分為3步

1,如果有Observer處于未同步狀态,則繼續同步,否則直接傳回。

2,使用目前Lifecycle的State和所有Observer中State最大的比較,如果mState較小,說明我們需要遞減狀态,執行backwardPass方法。例如狀态從RESUMED遞減到STARTED,事件為ON_PAUSE。

3,使用目前Lifecycle的State和所有Observer中State最小的比較,如果mState較大,說明我們要遞增狀态,執行forwardPass方法。例如狀态從CREATED遞增到STARTED,事件為ON_START。

下面我們看一下isSynced方法,可以看到,實作非常簡單,去除所有Observer中的最大狀态,最小狀态,并和Lifecycle的狀态進行比較。也就是所有Observer的狀态都已經被同步為了Lifecycle的狀态,才算同步完成。

private boolean isSynced() {
    if (mObserverMap.size() == ) {
        return true;
    }
    //擷取所有Observer中的最大狀态
    State eldestObserverState = mObserverMap.eldest().getValue().mState;
    //擷取所有Observer中的最小狀态
    State newestObserverState = mObserverMap.newest().getValue().mState;
    //判斷Observer中的所有狀态都和目前Lifecycle的狀态一緻了,則說明我們已經同步完成
    return eldestObserverState == newestObserverState && mState == newestObserverState;
}
           

下面我們在來看一下遞增狀态的forwardPass方法,該方法首先擷取一個按添加Observer順序的疊代器,然後周遊所有的Observer,對每一個Observer,遞增其狀态并通過dispatchEvent分發生命周期事件,直到其狀态遞增到Lifecycle的mState為止。這樣既完成了所有Observer的狀态同步和事件分發。

private void forwardPass() {
    //擷取一個按添加Observer順序的疊代器
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    //周遊所有Observer
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        //如果目前Observer的State小于mState,則遞增遞增目前狀态
        while ((observer.mState.compareTo(mState) <  && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            //使用我們之前介紹的ObserverWithState類的dispatchEvent方法分發生命周期事件
            //該事件最終會分發到我們的Observer的注解方法中
            observer.dispatchEvent(mLifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}
           

至于backwardPass方法,和上面很類似,僅僅是把狀态遞增改為了遞減,這裡就不分析了。

到這裡,我們就基本分析完了Lifecycle的流程和實作原理,下面我們用一張時序圖來作為總結。注意我們隻畫了addObserver和ON_CREATE事件的傳遞過程,其他生命周期事件的傳遞與此類似,就不畫了。

Android architecture components學習筆記1-Lifecycle源碼分析

Lifecycle設計思路借鑒

分析完了Lifecycle的使用,流程和代碼,我們可以思考一下它的設計思路是否能對我們有所借鑒,畢竟對于很多庫和架構,我們未必會直接使用到我們自己的項目中,但是閱讀了它的設計思路和源碼後,想想我們平時的代碼設計和實作中有什麼可以借鑒的閃光點,如果能把這些設計思路用到我們自己的項目中,也是不錯的。我個人以為Lifecycle有以下幾個值得借鑒的地方。

1,ReportFragment的使用,Fragment是我們平時常用的ui元件,我們一般用它來組織界面顯示,達到複用的目的。而Lifecycle向我們展示了Fragment的另外一種用法,即完全不用來展示界面,而僅僅是嵌入到宿主Activity中,用來傳遞生命周期。這就告訴我們,fragment可以做的事情不僅僅是展示界面,如果我們想象力豐富一下,它還可以做更多的事情,例如這裡的監聽Activity生命周期,以及之後要介紹的AAC元件ViewModel中的作為資料容器。

2,注解和反射的使用,我們其實可以在LifecycleObserver接口中定義7個生命周期方法on_create,on_start等,讓其他類來實作這些接口,達到不使用注解和反射的目的,但是這樣就需要我們覆寫所有的方法,哪怕我們并不需要某些生命周期事件,而Lifecycle為了使用的靈活性。采用了運作時注解和反射的方式,大家都知道,反射對性能是有一定消耗的,是以Lifecycle中對于注解方法采用了一次查找,之後緩存的方式,來應該該問題。大家在使用反射和運作時注解時也可以借鑒。