淺析 - Android Lifecycle Component
- 前言
- 簡要介紹相關類
- Lifecycle的初始化流程怎樣的?
- Lifecycle的狀态如何改變以及如何分發的?
- Lifecycle是如何解析生命周期狀态的?
前言
關于
Lifecycle
基礎相關的使用與概念請移步這裡:
- https://blog.csdn.net/guiying712/article/details/81176039#處理-onstop-事件
- https://developer.android.com/topic/libraries/architecture/lifecycle?hl=zh-cn
提出幾個問題,友善下面一一回答:
-
的初始化流程怎樣的?Lifecycle
-
的狀态如何改變以及如何分發的?Lifecycle
-
是如何解析生命周期狀态的?Lifecycle
簡要介紹相關類
Lifecycle
其内部定義了具有Android生命周期的事件與狀态。
LifecycleOwner
代表具有Android生命周期的類。 它最主要的實作類就是
AppCompatActivity
。
LifecycleObserver
标記一個類可以接收生命周期事件的回調。
LifecycleRegister
是
Lifecycle
的具體實作,可以處理多個觀察者,内部用來處理狀态,分發事件。
!
Lifecycle的初始化流程怎樣的?
一個元件再好用,如果不經過初始化,也是無根之水。 通過對生命周期注冊流程的反跟蹤,最後可以找到
android.arch.lifecycle.ProcessLifecycleOwnerInitializer
類,它作為
Lifecycle
元件初始化的開始。
由于其繼承自
ContentProvider
,那麼必須要在
AndroidManifest.xml
檔案中顯示注冊
ProcessLifecycleOwnerInitializer
才會被初始化。
在建構Apk的過程中,Android Studio會将多個子產品的
AndroidManifest.xml
合并到一起,是以檢視一下build目錄中,是否存在被合并的
AndroidManifest.xml
檔案。
app/build/intermediates/merged_manifests/debug/AndroidManifest.xml
可以很明顯的看到
<provider>
标簽在
AndroidManifest.xml
中被注冊。
<application
.... >
....
<provider
android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="com.example.application.lifecycle-trojan"
android:exported="false"
android:multiprocess="true" />
....
</application>
下面跟着一張時序圖,來捋清楚
Lifecycle
的初始化流程。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90TUZFDaXF2bwhlWwpkMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zN1QjN1UTNwIjMykDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
雖然涉及到的類很多,但是邏輯很多簡單,都是直接初始化。
其中核心的邏輯就是監聽
Activity
和
Fragment
的全局生命周期回調,最後在
Activity
建立時向其中添加一個
ReportFragment
,使用其作為生命周期的分發起始點。而當
Activity
和
Fragment
生命周期狀态發生改變時,都通過
LifecycleRegistryOwner
來處理生命周期狀态的改變。
// 注冊Activity的生命周期回調
((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
// 注冊Fragment的生命周期回調
((FragmentActivity) activity).getSupportFragmentManager() .registerFragmentLifecycleCallbacks(mFragmentCallback, true);
// injectIfNeededIn,添加ReportFragment到宿主Activity中。
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
Lifecycle的狀态如何改變以及如何分發的?
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
上文曾說過,
ReportFragment
是分發的核心類,當其生命周期變化時會分發對應的事件,最後走到
LifecycleRegister.handleLifecycleEvent(Lifecycle.Event)
中。
handleLifecycleEvent()
内部做了兩件事:
- 擷取事件對應的下一個狀态
- 改變目前狀态到下一個狀态,并同步分發事件
雖然
getStateAfter()
很短,但是還是看圖更易了解:
假設
ReportFragment
分發了
Lifecycle.Event.ON_RESUME
,那麼根據這個方法,可以得到對應的狀态為
RESUMED
。
最後關鍵的步驟就是将各個觀察者的生命周期狀态依次移動到正确的狀态,
sync()
将該過程分為兩個步驟,具體如下:
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 (... mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
這裡以将狀态向前移動為例(
CREATED => RESUME
)來分析下
fowardPass()
方法:
private void forwardPass(LifecycleOwner lifecycleOwner) {
// 升序排序
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
...
// 若目标觀察者的狀态小于目前狀态,那麼目前狀态對應的事件,并進行分發。
while ((observer.mState.compareTo(mState) < 0 && ... ) {
...
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
...
}
}
}
最後已一個時序圖結尾:
Lifecycle是如何解析生命周期狀态的?
因為觀察者内部是使用注解來标記生命周期方法的,也就不可避免的需要使用的反射。為了反射開銷比較大,是以使用了
ClassInfoCache
作為緩存。 整個流程比較簡單,就不詳細介紹了。
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun create() {
Log.d(TAG, "create() called ")
}
}