上篇文章中我們以繼承自 AppCompactActivity 這種情況來分析 Lifecycle 的源碼。本篇,我們將一起來分析下繼承自普通 Activity 這種情況下的源碼分析。
support library 27.0.0與 28.0.0 下使用的區別
之前說道,我們如果不繼承自 AppCompactActivity ,就只能自己手動在各 Activity 的生命週期方法中調用 markState(...) 函數來進行生命週期事件的分發。類似下圖:
但是如果你是用的是 27.0.0 版本的 support library ,你會發現你這樣實現的話是沒有效果的。
你還需要自己再手動調用 LifecycleRegistry 類的handleLifecycleEvent(...)
方法。
因爲 support library 27.0.0 下引入的 Lifecycle 的 common
庫的版本是 1.0.0(引入的 runtime 庫會自動引入 common 等庫),而 28.0.0版本引入的則是 1.1.1,二者的實現是有差別的,可以看下下面的源碼。
先來看1.1.1
版本下實現:
再來看下1.0.0
版本下實現:
可以看出,在 1.0.0 版本中,markState()
方法,僅僅是對 State 進行了賦值,而沒有對事件進行分發,而在 1.1.1 版本中則是在標記 State 的時候,同時進行事件的分發。這就不用我們再像之前那樣寫那一行繁瑣的代碼,還要去根據生命週期方法來判斷傳進去什麼 Event 作爲參數。
那我們本篇所講的繼承自普通 Activity 情況下的源碼解析,就是這個?當然不是。如果是這個,那就沒有必要再講了,因爲這些在上篇中已經講過了。繼續往下看。
引入 extensions 庫之後的源碼解析
雖然通過重寫 Activity 生命週期,並通過在各方法中僅添加一行mLifecycleRegistry.markState()
代碼就能實現生命週期的感知。但是,作爲推動社會發展的“懶人” -- 程序員,自然想通過更簡單的方式來解放右手。辦法總比困難多。
從上一篇文章我們知道,通過繼承 AppCompactActivity 這種實現方式中核心就是向 Activity 中注入一個空的 Fragment--ReportFragment。我們能不能也通過這種方式,動態的向 Activity 中注入這個 ReportFragment 呢?
我當時是這麼想的。之前閱讀8.1
的系統源碼的時候,瞭解到能通過 Application
的registerActivityLifecycleCallbacks()
方法監聽 Activity 的生命週期。說明這條路是可行的。
當然,我們沒必要自己進行實現,因爲 Google 已經幫我們實現了。Google 爲我們提供了一個extensions
庫,我們需要單獨引入:
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
該庫同時也會自動引入 LiveData 和 ViewModel 相關庫,關於這二者,我們之後的文章中會另行講解。
引入該庫之後,我們的使用方式,就跟繼承自 AppCompactActivity 基本相同,唯一的不同點就是我們需要自己實現 LifecycleOwner :
引入該庫之後,我們Command/Ctrl+鼠標左鍵
,點擊ReportFragment,會發現使用到它的有兩個類:LifecycleDispatcher.java
和 ProcessLifecycleOwner.java
這兩個類,而這二者,就是android.arch.lifecycle:extensions:1.1.0
這個庫下的類:
那我們就先追蹤ReportFragment.injectIfNeededIn(activity);
在LifecycleDispatcher.java
類中的調用:
ReportFragment.injectIfNeededIn(activity);
這行代碼是在 LifecycleDispatcher 的靜態內部類DispatcherActivityCallback
的 onActivityCreated(...) 方法中調用的。而DispatcherActivityCallback
又繼承自EmptyActivityLifecycleCallbacks
,EmptyActivityLifecycleCallbacks
是啥?它其實就是Application.ActivityLifecycleCallbacks
接口的空實現類。
看到這就對上了,原來 Google 採用的就是我們前面提到的方式,通過Application.ActivityLifecycleCallbacks
進行監聽。
繼續回到上面的 LifecycleDispatcher
的源碼查看,發現靜態內部類 DispatcherActivityCallback
的實例化是在LifecycleDispatcher
類的static
方法init()
中,在該方法中進行監聽器的註冊:
這裏面,就真正的看到了通過Application
的registerActivityLifecycleCallbacks
來註冊監聽器。
繼續追蹤 LifecycleDispatcher#init(...)
方法,就進入了ProcessLifecycleOwnerInitializer
類的onCreate()
方法:
在其 onCreate() 方法中,進行了LifecycleDispatcher 的初始化,並且也進行了ProcessLifecycleOwner 的初始化。關於ProcessLifecycleOwner ,這裏我們簡單點下,它也實現了 LifecycleOwner 接口,主要用來監聽應用的前後臺切換。
回過來繼續看ProcessLifecycleOwnerInitializer
,它繼承自 ContentProvider ,也就是說,它是個 ContentProvider ,但通過看源碼,發現它對 ContentProvider 的各種方法都進行了空實現。其實,這裏就是利用了 ContentProvider 的隱式加載。它的 onCreate() 方法執行時機是在Application 的 onCreate()方法之前。這樣它就能通過 Application 來監聽 Activity 的創建,並判斷是否已經添加過了一個空UI的 ReportFragment。若沒有,就進行添加。這種設計真的是太妙了。
我們知道,四大組件都是要在 AndroidManifest.xml 文件中進行生命的。那這個 ContentProvider 類型的 ProcessLifecycleOwnerInitializer 又是在什麼時候聲明的呢?
我們找到extensions
庫,通過如下方式查看它的下載位置:
然後打開這裏的AndroidManifest.xml
,會發現,在這裏進行了聲明。
這裏的AndroidManifest.xml
最終會合併入我們app module
的AndroidManifest.xml
文件中。
至此,我們就對 Lifecycle 的源碼進行了完全的解析。包括繼承自普通 Activity 和繼承自AppCompactActivity這兩種情況。
補充
這裏,再進行一點補充。如果我們使用的是 Java8,我們可以通過依賴下面這個庫,來避免使用@OnLifecycleEvent(...)
註解的方式進行生命週期回調方法的聲明:
implementation "android.arch.lifecycle:common-java8:1.1.1"
這個庫其實就一個 DefaultLifecycleObserver.java
接口類。之後我們需要 LifecycleObserver 的時候,一般實現 DefaultLifecycleObserver 接口即可(不用再去直接實現 LifecycleObserver 接口),使用方式變成了下面這樣:
可以看到,這裏我們直接在覆寫的生命週期對應回調方法中寫入我們的邏輯代碼即可。更加簡潔。
後續文章會繼續講 LiveData 及 ViewModel 等Architecture Components,歡迎關注公衆號類獲取最新消息。