Android官方提供了一系列架構組件,其名曰 jetpack。本文從源碼的角度深刻理解 Lifecycle 組件的原理。android
Lifecycle
組件是官方架構組件的基石,不少組件也是依賴它來實現的。它能感知Activity/Fragment(或你的自定義組件)的生命週期而且將生命週期狀態通知給其餘對象。bash
不少開發者必定有這樣的經歷,一個Activity/Fragment的各個生命週期方法內處理大量的業務邏輯代碼,有了 Lifecycle
咱們就能夠將任意的業務邏輯拆分,單獨寫到一個類中。架構
如下是使用示例:app
class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLifecycle().addObserver(new LearnLifecycleObserver());
}
}
/**
* 學習LifecycleObserver
* @author sunxianglei
* @date 2019/05/30
*/
public class LearnLifecycleObserver implements LifecycleObserver {
private static final String TAG = "LearnLifecycleObserver";
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void discoverLifecycle(){
Log.d(TAG, "I discover lifecycle component, it looks well");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void startLearn(){
Log.d(TAG, "I start to learn lifecycle, I see see if it's really well");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void stopLearn(){
Log.d(TAG, "what a fu*k! it's too difficult, I give up");
}
}
複製代碼
Lifecycle
的使用仍是很簡單的,可是若是不知道其實現原理,你就沒法靈活的排查問題、理解其餘的組件,因此咱們須要看源碼。ide
提出問題源碼分析
大佬說過,看源碼必定要帶着問題去看,只要將問題原理搞清楚了就能夠出來了,不要沉迷於源碼細節,很容易迷失本身。根據上面的示例,自定義類實現了 LifecycleObserver
接口,而後將其對象添加到Lifecycle
中。我對此提出兩個疑問:學習
Lifecycle
是什麼,添加 LifecycleObserver
的流程是怎樣的?接下來就帶着問題去看源碼了。ui
Tips: debug 看調用堆棧是個很不錯的手段。google
第一步確定是跟getLifecycle()
方法,這個方法是 LifecycleOwner
的一個接口方法(經過實現 LifecycleOwner
接口能夠製做一個自定義管理生命週期分發的組件,這個本文不討論)。而後你會發現 Android 系統源碼在 SupportActivity
類實現了這個接口,在 SupportActivity
類中有個 mLifecycleRegistry
對象,而後發現LifecycleRegistry
繼承了Lifecycle
抽象類,直接貼出代碼:spa
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
public abstract State getCurrentState();
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED
}
}
複製代碼
每一個方法和變量其實都有詳細的註釋,看下注釋基本能明白他們的做用。貼一下官方的生命週期狀態和事件圖:
**State 是節點, Event 是鏈接每一個節點的線。**Event 的狀態徹底能夠按 Activity 的生命週期來理解,都是一一對應的,State 看起來是缺失了 PAUSED、STOPED,其實它的 PAUSED 就是 STARTED,STOPED 是 CREATED。總的來講,Event 就是改變生命週期的事件,State 是目前 Activity/Fragment 所處生命週期的狀態。
LifecycleRegistry
做爲Lifecycle
的惟一實現類,是至關關鍵的一個類,先看下它是如何添加自定義LifecycleObserver
的。
public void addObserver(LifecycleObserver observer){
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
......
}
複製代碼
這段代碼建立了 ObserverWithState
對象,並將 LifecycleObserver
和ObserverWithState
對象經過構造方法傳進去,而後以鍵值對的形式將LifecycleObserver
做爲key, ObserverWithState
做爲value進行存儲。接着看下 ObserverWithState
構造方法內作了什麼事:
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
}
複製代碼
再跟進 getCallBack
方法內會發現最後返回對象是new ReflectiveGenericLifecycleObserver
, ReflectiveGenericLifecycleObserver
實現了 GenericLifecycleObserver
接口,它的構造方法內保存了咱們自定義的LifecycleObserver
,而且解析生成一個 CallbackInfo
對象,咱們能夠把這個類理解成自定義LifecycleObserver
的包裝類。
class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
}
複製代碼
暫時就先跟到這裏吧,由於咱們的目的就是了解 Lifecycle
抽象類是個什麼東西,是如何添加自定義Observer的,根據上面的源碼閱讀就能回答了。
Lifecycle
管理着組件(Activity/Fragment)的生命週期事件和狀態,LifecycleRegistry
是其惟一實現類,真正的添加操做發生在addObserver()
方法內,主要是構造出ObserverWithState
對象,其內部包裝 ReflectiveGenericLifecycleObserver
對象,而 ReflectiveGenericLifecycleObserver
包裝自定義Observer
對象,而後將ObserverWithState
對象放到集合中,以後會使用到。
既然是生命週期事件分發,那確定得看生命週期方法吧,先看下SupportActivity.OnCreate
方法發現它建立了一個 ReportFragment
,這是個空白的Fragment
,主要用來分發生命週期的,果不其然,ReportFragment
內部的生命週期方法都分發了Event:
// ReportFragment
// 不一樣的生命週期方法會調用此方法,傳進不一樣的Event
private void dispatch(Lifecycle.Event event) {
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
複製代碼
// LifecycleRegistry
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
複製代碼
//該方法將Event轉成State,正好對應以前Event和State那張關係圖
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;
}
}
複製代碼
moveToState
方法內會調用到 sync()
方法:
private void sync() {
......
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;
}
複製代碼
根據 State 的狀態會有前進、後退兩種邏輯,前進就是生命週期狀態和事件圖中從左往右的線路,後退就是生命週期狀態和事件圖從右往左的線路,看下比較難理解的後退邏輯:
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
// 第一層循環:遍歷全部的自定義LifeObserver
while (descendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
// 第二層循環:根據當前Activity/Fragment的生命週期狀態
// 對比自定義LifecycleObserver所處的狀態,而後按狀態順序一層層的更新狀態
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));
// 調用 ObserverWithState.dispatchEvent
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
// 此方法是將State按後退邏輯轉換成對應的Event
private static Event downEvent(State state) {
switch (state) {
case INITIALIZED:
throw new IllegalArgumentException();
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
case DESTROYED:
throw new IllegalArgumentException();
}
}
複製代碼
接下來走到ObserverWithState.dispatchEvent
方法,以前說到過 ObserverWithState
是 ReflectiveGenericLifecycleObserver
的包裝類。
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
// 調用 ReflectiveGenericLifecycleObserver.OnStateChanged 方法
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
複製代碼
以前還說到過 ReflectiveGenericLifecycleObserver
是自定義LifecycleObserver
的包裝類,感受這裏即將要分發到LifecycleObserver
裏去了啊!
public void onStateChanged(LifecycleOwner source, Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
複製代碼
其實調用CallbackInfo.invokeCallBacks
基本就要結束了,不過咱們還不知道 CallbackInfo
是怎麼來的, 這也是上節遺留的一個疑點,即在 ReflectiveGenericLifecycleObserver
構造方法內調用了這麼一句mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
進去看看 CallbackInfo
是怎麼建立的:
private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
// MethodReference 和 Lifecycle.Event HashMap集合,
// 每一個自定義LifecycleObserver的method對應一個Event,能夠有多個method用一樣的Event
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
for (Method method : methods) {
// 解析註解
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if (annotation == null) {
continue;
}
Lifecycle.Event event = annotation.value();
MethodReference methodReference = new MethodReference(callType, method);
// handlerToEvent集合添加對應的method和Event鍵值對
verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
}
// CallbackInfo構造方法內進一步針對一種Event對應多個Method的狀況,整理成一個HashMap
CallbackInfo info = new CallbackInfo(handlerToEvent);
return info;
}
複製代碼
上述代碼省略了一些不重要的代碼,MethodReference
對象其實徹底能夠看作是 Method
,前者是後者的包裝類。而後咱們回到 ReflectiveGenericLifecycleObserver.onStateChanged
方法中,裏面調用了CallbackInfo.invokeCallbacks()
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
// 根據Event拿到一組註解了此Event的方法,而後遍歷調用。
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
target);
}
private static void invokeMethodsForEvent(List<MethodReference> handlers,
LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
if (handlers != null) {
for (int i = handlers.size() - 1; i >= 0; i--) {
handlers.get(i).invokeCallback(source, event, mWrapped);
}
}
}
複製代碼
// MethodReference.invokeCallback 方法進去就是真正調用 Method.invoke 方法的地方
void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
switch (mCallType) {
case CALL_TYPE_NO_ARG:
// 沒有參數的方法會調到這裏
mMethod.invoke(target);
break;
case CALL_TYPE_PROVIDER:
mMethod.invoke(target, source);
break;
case CALL_TYPE_PROVIDER_WITH_EVENT:
mMethod.invoke(target, source, event);
break;
}
}
複製代碼
到此爲止,一次生命週期事件分發就結束了。
每次 ReportFragment
生命週期狀態的變化會分發Lifecycle.Event
,接着調到 LifycycleRegistry
根據目前生命週期狀態和以前狀態對比來決定是前進仍是後退,而後會通過 ObserverWithState->ReflectiveGenericLifecycleObserver -> CallbackInfo -> MethodReference
,最終經過反射真正調用到自定義LifecycleObserver
添加了註解的方法。
大佬說過,看源碼必定要畫類圖和時序圖,配合源碼食用會更加美味。
類圖:
時序圖:
根據以上兩張圖作一個總結:
SupportActivity
實現了LifecycyleOwner
,並經過getLifecycle()
方法得到Lifecycle
惟一實現類LifecycleRegistry
的實例,這時咱們就能夠經過addObserver
方法添加咱們想要感知生命週期的自定義對象了。並且咱們也能夠按照這種模式,本身寫一個實現了LifecycleOwner
接口的組件。LifecycleObserver
對象後,這個對象就會被ReflectiveGenericLifecycleObserver
包裝,同時會經過解析方法註解生成一個CallbackInfo
用做後期的Event分發,ReflectiveGenericLifecycleObserver
又會被ObserverWithState
包裝,ObserverWithState
加入一個集合後就表明生命週期狀態改變時會通知到全部的LifecycleObserver
。SupportActivity.OnCreate
方法中會建立一個空白ReportFragment
,當它的生命週期State
改變時會結合以前的State作對比決定是前進仍是後退State
,而後會依次調用 ObserverWithState -> ReflectiveGenericLifecycleObserver.onStateChanged -> CallbackInfo.invokeCallbacks -> MethodReference.invokeCallback
,最後會調到LifecycleObserver
註解了Lifecycle.Event
的方法中。參考資料