這篇文章旨在用最簡單的方式教會你Lifecycle如何使用,及它的工作原理。
Lifecycle介紹
Lifecycle是Google推出的JetPack框架元件的一個,主要是用來感知Activity和Fragment的生命週期,可以幫你寫出更簡潔,通用的程式碼。
Lifecycle使用
總共兩步
- 第一步,編寫自己的Observer類檔案,並實現對應的監聽方法,通過註解實現對響應生命週期方法的監聽,程式碼如下:
public class MyLifeObserver implements LifecycleObserver {
private static final String TAG = "MyLifeObserver";
// OnLifecycleEvent()內的註解Lifecycle.Event.XXX 對應不同的生命週期方法,你可以根據需要監聽不同的生命週期方法。
// 方法名可以隨意,這裡為了方便理解定義為onResumeListener()。
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResumeListener() {
Log.d(TAG, "onResume: ");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPauseListener() {
Log.d(TAG, "onPause: ");
}
@OnLifecycleEvent(Event.ON_DESTROY)
public void onDestoryListener() {
Log.d(TAG, "onDestory: ");
}
複製程式碼
- 第二步在被監聽的Activity/Fragment內註冊:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLifecycle().addObserver(new MyLifeObserver());
}
}
複製程式碼
不管你信不信,程式碼已經寫完了!
我們跑一下程式碼:
2019-02-28 12:00:40.068 com.example.lifecycledemo D/MyLifeObserver: onResume:
2019-02-28 12:00:46.091 com.example.lifecycledemo D/MyLifeObserver: onPause:
2019-02-28 12:00:46.416 com.example.lifecycledemo D/MyLifeObserver: onDestory:
複製程式碼
Log 顯示我們寫的 Observer 內的方法的確在 Activity 的指定週期內執行了。恭喜你,已經能夠使用 Lifecycle 了!
但是注意幾點:
- 通常我們會 把MyLifeObserver 作為內部類寫在另一個 Activity/Fragment 中,以方便在監控到生命週期方法後做一些業務操作,以上程式碼為了快速看到效果而做了省略。
- 注意上面 Activity 的程式碼中,我們的 Activity 繼承了AppCompatActivity,AppCompatActivity 和 Fragment 都實現了LifecycleOwner 介面(Support Library 26.1.0之後的版本),所以可以直接拿來使用。如果你被監控的 Actiivty 是自定義的 Activity,需要手動繼 承LifecycleOwner,具體操作如下:
1. 實現LifecycleOwner介面,並重寫getLifecycle方法。
2. 手動在每個生命週期方法中做標記。
複製程式碼
具體程式碼如下:
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
//建立Lifecycle物件
mLifecycleRegistry = *new*LifecycleRegistry(this);
//做標記
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
//新增觀察者
getLifecycle().addObserver(new MyLifeObserver());
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
@Override
public void onStart() {
super.onStart();
//做標記
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@Override
protected void onResume() {
super.onResume();
//做標記
mLifecycleRegistry.markState(Lifecycle.State.RESUMED);
}
@Override
protected void onDestroy() {
super.onDestroy();
//做標記
mLifecycleRegistry.markState(Lifecycle.State.DESTROYED);
}
}
複製程式碼
至此,Lifecycle 的使用方法已經介紹完了,因為 AppCompatActivity 已經幫我們實現了 LifecycleOwner 介面,所以同學們注意活學活用。
比如:在封裝網路請求工具時候,傳入當前 Activity 物件,當 Activity 物件生命週期為 Destory 時,撤銷請求網路的操作。
Lifecycle 用武之地還有很多,這裡只介紹最基礎的,你現在可以思考如何通過 Lifecycle 來優化你的專案了。
如果你對Lifecyle的工作原理有興趣,請繼續閱讀,我會帶著你從原始碼一步一步完全理解 Lifecycle 的工作原理。
如果沒有興趣,可以直接拉到文章末尾看總結~
Lifecycle的工作原理
我們就以使用到的幾個類為切入口,分析 Lifecycle 的工作原理。 我們主要點進這幾個類看(Crtl+單擊類名):LifecycleOwner.java,Lifecycle.java,LifecycleRegistry.java。
LifecycleOwner.java
這個很簡單,LifecycleOwner定義了一個getLifecycle()方法,通過@NonNull強制我們返回Lifecycle物件。程式碼如下:
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
複製程式碼
Lifecycle.java
程式碼如下:
public abstract class Lifecycle {
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
@MainThread
@NonNull
public abstract State getCurrentState();
@SuppressWarnings("WeakerAccess")
public enum Event {
ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,
ON_DESTROY,ON_ANY
}
@SuppressWarnings("WeakerAccess")
public enum State {
DESTROYED,INITIALIZED,CREATED,STARTED, RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
複製程式碼
Lifecycle的程式碼也並不多,注意它是一個抽象類。Lifecycle內部通過兩個列舉分別定義了元件的生命週期的狀態和事件。
下面這張圖摘自Android開發者官網,介紹了State和Event的關係:
簡單說下這個圖怎麼看:看箭頭,比如 ON_CREATE 箭頭表示:State 從 INITIALIZED 變為 CREATED,會觸發 ON_CREATE 的 Event。依次類推。
LifecycleRegistry.java
這個類的程式碼比較多,是 Lifecycle 的子類,也是監聽元件宣告週期的核心類。我們就從使用到的方法一個一個來看:
A.構造方法,主要初始化了 mLifecycleOwner 和當前元件的狀態(mState),沒什麼說的。
publicLifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
複製程式碼
B. 我們在 Lifecycle 的使用部分,繼承了 LifecycleOwner,並在元件的生命週期內呼叫了 markState()方法。點進去如下:
public void markState(@NonNull State state) {
moveToState(state);
}
複製程式碼
C. 省去了一些複雜邏輯的程式碼,我們找到了這個核心的方法 sync():
private void moveToState(State next) {
...
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
複製程式碼
D. 同樣在 sync()方法中,忽略掉邏輯程式碼,我們發現了正真執行的兩個方法:backwardPass(),forwardPass()
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
while(!isSynced()) {
mNewEventOccurred = false;
if(mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState > newest = mObserverMap.newest();
if(!mNewEventOccurred && newest != null && mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
複製程式碼
E. 在 backwardPass()和 forwardPass(),呼叫了 observer.dispatchEvent(),看名字想必就是傳送事件的方法了:
private void forwardPass(LifecycleOwner lifecycleOwner) {
...
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
...
}
private void backwardPass(LifecycleOwner lifecycleOwner) {
...
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
...
}
複製程式碼
F. 我們點選 dispatchEvent()方法,進入了下面這個靜態內部類中,這個類中,就可以確定了:Observer(下面程式碼中的 mLifecycleObserver)觸監聽定生命週期的方法在這裡被觸發了。 但是我們如何確定這個方法的 mLifecycleObserver 就是我們實現的 Observer 呢?這個靜態類還有一個方法,我們點選一下看它在哪裡被呼叫了:
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
複製程式碼
G. 很高興,我們來到了 addObserver()方法,你一定還記得我們在講解 Lifecycle 使用部分是,繫結 Observer 就是使用這個方法。
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState*statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState*previous = mObserverMap.putIfAbsent(observer, statefulObserver);
...
}
複製程式碼
H. 最後我們看一眼 LifecycleObserver介面(觀察者),發現它是空的。其實我們看到註解應該猜到,系統是通過 apt-processor(註釋處理器)將我們的 Observer 轉換成 Lifecycle 真正需要型別 的Observer,下面是 OnLifecycleEvent 註解的宣告:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnLifecycleEvent {
Lifecycle.Event value();
}
複製程式碼
總結
看到這裡,相信大家對 Lifecycle 的工作原理已經理解的差不多了吧,跟介面回撥類似,我們建立了 Obersver 的物件,然後將 Obersver 的引用交給 Lifecycle,在元件生命週期方法執行時,呼叫 Observer 的相應的方法。
當然,我們自己也可以寫一套介面回撥來監控元件的生命週期,但是我們不得不考慮在哪裡設定監聽器,生命週期的問題。 其實我們使用 Lifecycle 真正的理由是,Lifecycle(LifecycleRegistry)類幫我們處理了大量的與宿主元件生命週期相關的問題,使我們的程式碼更簡潔。專心處理業務邏輯即可。END
我是雷加,如果您喜歡我的文章,請留下你的贊;如有疑問和建議,請在評論區留言
我的Github,歡迎關注~
Jetpack 專欄:
Lifecycle:Jetpack系列 - Lifecycle從入門到原始碼
ViewModel:Jetpack系列 - ViewModel從入門到原始碼
LiveData:Jetpack系列 - LiveData從入門到原始碼
Palette:Jetpack系列 - Palette 入門指南
--------------------------------------- The End