LifeCyle的理解

產生的背景

先看個代碼

class LifeCycleOldActivity : AppCompatActivity(){
    lateinit var presenter: Presenter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        presenter = Presenter()
        presenter.onCreate()
    }

    override fun onDestroy() {
        super.onDestroy()
        presenter.onDestroy()
    }
}

class Presenter{
    fun onCreate(){}
    fun onDestroy(){}
}

乍一看,很普通的邏輯,onCreate創建,onDestroy銷毀,規范合理嚴謹。這是咱們祖輩總結出的模板性代碼。但是這個有以下幾個問題:

  1. 頁面多了這種代碼將到處都是
  2. Activity里太多P的代碼,依賴度太高
  3. 執行順序上不一定有保證,presenter.onDestroy不是一定會在presenter.onCreate后執行的,有可能出現onDestroy都走到了,onCreate后的一些方法還在執行
  4. 感知其它方法又要搞一大堆代碼,乏味還不一定對

主要解決的痛點

核心還是優雅的去感知生命周期組件:

  • 將聲明周期感知的邏輯從生命周期組件中分離出來,將感知對象作為生命周期組件的一個觀察者就好
  • 感知自由度高且漸變,想感知啥的話注解加一下就好
  • LifeCycle內部處理嚴格,基于狀態去處理,可以自由的根據狀態去執行相應邏輯,確保生命周期執行的合理和安全性
class LifecycleNewActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //LifecycleNewActivity 實現了LifecycleOwner 是一個生命周期組件
        //添加對應的觀察者
        lifecycle.addObserver(NewPresenter())
    }
    fun requestSuccess(){
        //可以確保此處執行的安全性
        if(lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)){
            //refresh 
        }
    }
}

/**
 * 生命周期組件的觀察者,在這里感應生命周期變化就好
 */
class NewPresenter : LifecycleObserver{
    //通過注解來決定感知啥事件
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(){
        
    }
}

核心類說明

LifeCycle
  • 三個核心方法
    1. addObserver:添加觀察者
    2. removeObserver:移除觀察者
    3. getCurrentState:獲取當前狀態
  • 兩個枚舉對象
    1. Event 事件
      ON_CREATE,
      ON_START,
      ON_RESUME,
      ON_PAUSE,
      ON_STOP,
      ON_DESTROY,
      ON_ANY
    2. State 狀態
      • INITLALIZED 初始態:這是他被構造但還沒收完成onCreate方法時的狀態-->onCreate方法體狀態
      • CREATED 創建態:在兩種情況下會達到此狀態:在onCreate調用之后;就在onStop調用之前-->onStart onStop 方法體狀態
      • STARTED 啟動態:在兩種情況下會達到此狀態:在onStart調用之后;就在onPause調用之前-->onResume onPause 方法體狀態
      • RESUMED 可見態:調用onResume后達到此狀態-->頁面可見后onResume最后隨便一個異步后就是此狀態了
      • DESTORYED 銷毀態:此狀態后,將不再分發其它事件;在調用onDestroy方法前就會到達這個狀態
LifecycleOwner

生命周期的擁有者,只有一個接口方法Lifecycle getLifecycle();實現了該接口的類,被定義為生命周期組件。

LifecycleObserver

生命周期組件的觀察者,這是一個沒有接口方法的接口,標識性接口,實現該接口的類在運行時通過解析OnLifecycleEvent注解達到指定生命周期事件的觀察者的回調

LifecycleRegistry

系統提供的Lifecycle的實現,提供了如何感應生命周期變化的標準實踐

源碼段解析

以Activity為例解析生命周期感知的源碼流程

//實現了LifecycleOwner
public class ComponentActivity ... implements LifecycleOwner  {
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        ...
        // 轉接給ReportFragment去影響生命周期,這也是Glide影響生命周期的方案
        ReportFragment.injectIfNeededIn(this);
        ...
    }
}
public class ReportFragment extends android.app.Fragment {
   ... 
    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // 29+版本 通過LifecycleCallbacks感知生命周期
            LifecycleCallbacks.registerIn(activity);
        }
          //通過添加個無頁面Fragment感知生命周期
        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 onActivityCreated(Bundle savedInstanceState) {
        ...
        //分發生命周期事件
        dispatch(Lifecycle.Event.ON_CREATE);
    }
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
        //onCreate執行后才會發送ON_CREATE事件
        @Override
        public void onActivityPostCreated(@NonNull Activity activity,
                @Nullable Bundle savedInstanceState) {
            dispatch(activity, Lifecycle.Event.ON_CREATE);
        }
}
    /**
     * 最終交由LifecycleRegistry的handleLifecycleEvent方法處理
     **/
    static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        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);
            }
        }
    }
}
public class LifecycleRegistry extends Lifecycle {
  public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
      //根據當前事件獲取下一個目標狀態
      State next = getStateAfter(event);
      //根據當前事件將狀態移動到對應狀態
      moveToState(next);
    }

    public void addObserver(@NonNull LifecycleObserver observer) {
        ...
        //粘性事件的源頭
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        ...
    }

    //移動狀態
  private void moveToState(State next) {
          //當前狀態和目標狀態一直,不繼續了
          if (mState == next) {
              return;
          }
          //修改當前狀態為目標狀態
          mState = next;
          //正在處理事件,或者正在添加觀察者暫不繼續
          if (mHandlingEvent || mAddingObserverCounter != 0) {
              mNewEventOccurred = true;
              // we will figure out what to do on upper level.
              return;
          }
          //修改處理事件中標注為true
          mHandlingEvent = true;
          //同步去處理狀態
          sync();
          //處理完后將標志改為false
          mHandlingEvent = false;
  }
  //同步生命周期狀態
  private void sync() {
          LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
          //生命周期擁有者為空了,直接拋異常,一般出現在被系統回收后,異常的意思是,擁有者被回收了,改狀態太晚了!
          if (lifecycleOwner == null) {
              throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                      + "garbage collected. It is too late to change lifecycle state.");
          }
          //還有未同步的觀察者的話會無限循環去進行狀態同步
          while (!isSynced()) {
              mNewEventOccurred = false;
              // no need to check eldest for nullability, because isSynced does it for us.
              if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                  //向后同步
                  backwardPass(lifecycleOwner);
              }
              Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
              if (!mNewEventOccurred && newest != null
                      && mState.compareTo(newest.getValue().mState) > 0) {
                  //向前同步
                  forwardPass(lifecycleOwner);
              }
          }
          mNewEventOccurred = false;
   }
  //true  都同步完了   false  還有未同步的
  private boolean isSynced() {
          if (mObserverMap.size() == 0) {
              return true;//木有觀察者,按都是已經同步過的處理
          }
          State eldestObserverState = mObserverMap.eldest().getValue().mState;
          State newestObserverState = mObserverMap.newest().getValue().mState;
          return eldestObserverState == newestObserverState && mState == newestObserverState;
  }
  private void backwardPass(LifecycleOwner lifecycleOwner) {
          ...
          //根據狀態映射回事件
          Event event = Event.downFrom(observer.mState);
          ...
          //想觀察者發送事件
          observer.dispatchEvent(lifecycleOwner, event);
          ...
          }
  }

  static class ObserverWithState {
        ...
        //分發事件
        void dispatchEvent(LifecycleOwner owner, Event event) {
            ...
            mLifecycleObserver.onStateChanged(owner, event);
            ...
        }
    }
}
//onStateChanged的實現
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    ...
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}
static class CallbackInfo {
        ...
        //通過反射調用LifecycleObserver被OnLifecycleEvent注解標注的方法
        @SuppressWarnings("ConstantConditions")
        void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
            invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
            invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
                    target);
        }
}
//事件與狀態的對象關系
public abstract class Lifecycle {
  ...
      //這個方法結合ReportFragment的dispatch的調用時機,完美的解釋了,當回調某個生命周期方法后所對應的狀態情況
      public State getStateAfter() {
            switch (this) {
                case ON_CREATE: // 這個事件時在onActivityPostCreated發送的也就是onCreate執行完后
                case ON_STOP: // 這個事件時在onActivityPreStopped時發送的也就是onStop執行之前
                    return State.CREATED; //綜合結論就是onCreate之后和onStop之間進入CREATED狀態
                case ON_START:
                case ON_PAUSE:
                    return State.STARTED;
                case ON_RESUME:
                    return State.RESUMED;
                case ON_DESTROY:
                    return State.DESTROYED;
                case ON_ANY:
                    break;
            }
            throw new IllegalArgumentException(this + " has no target state");
        }
  ...
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容