「Jetpack - Lifecycle梳理」
一、寫在前面
谷歌推出Jetpack系列已經(jīng)有一段時間了,作為AAC(Android Architecture Components)架構(gòu)組件基礎(chǔ),使開發(fā)的過程越來越規(guī)范化嗅回,遵循谷歌推薦的最佳做法不僅使App更加健壯;體驗更優(yōu)。代碼層面更加簡潔(Jetpack內(nèi)部幫我們處理了很多
)優(yōu)雅暗膜,消除了冗余的樣板代碼。
關(guān)于Jetpack系列的解析鞭衩,大佬們輸出了很多優(yōu)秀的文章学搜。學(xué)到了很多,這里還是自己系統(tǒng)的梳理一遍论衍,構(gòu)建自己的知識體系瑞佩,包括LiveData、ViewModel坯台、Room炬丸、WorkManager、Paging3蜒蕾、Compose等等稠炬。
二焕阿、Lifecycle是什么?
用于生命周期感應(yīng)型組件的構(gòu)建酸纲,可以根據(jù)Fragment捣鲸、Activity的生命周期狀態(tài)而自動調(diào)整自身的行為、操作
- Lifecycle是一個抽象類闽坡,用于存儲有關(guān)組件(Activity栽惶、Fragment)的生命周期狀態(tài)的信息,并允許其他對象觀察此狀態(tài)疾嗅。
- 使用兩種主要的枚舉跟蹤相關(guān)組件的生命周期狀態(tài)
事件Events
- 從框架和
Lifecycle
類分派的生命周期事件外厂。這些事件映射到 Activity 和 Fragment 中的回調(diào)事件。
狀態(tài)States
- 由
Lifecycle
對象跟蹤的組件的當(dāng)前狀態(tài)代承。 -
官網(wǎng)的結(jié)構(gòu)圖
三汁蝶、使用依賴
(早期的依賴已經(jīng)棄用了)
lifecycle-extensions
中的 API 已棄用。您可以為特定 Lifecycle 工件添加所需的依賴項论悴。
添加相關(guān)組件的依賴
dependencies {
val lifecycle_version = "2.4.0"
//without ViewModel or LiveData
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version")
//ViewModel(可選的)
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
// LiveData(可選的)
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
}
一般的使用Lifecycle都會搭配ViewModel掖棉、LiveData一起使用,構(gòu)建數(shù)據(jù)驅(qū)動UI型應(yīng)用膀估,可以說Lifecycle作為Jetpack的基石幔亥,循序漸進(jìn)的去掌握有助于理解深刻。
四察纯、生命周期的管理
- 生命周期的管理很重要
Android中的內(nèi)存泄漏問題很大一部分來源于對生命周期的管理不當(dāng)帕棉,資源在本應(yīng)該釋放的時候并沒有得到釋放。導(dǎo)致生命周期短的組件持有了生命周期長的組件最終導(dǎo)致內(nèi)存泄漏饼记,應(yīng)用Crash香伴。自定義View包含動畫時,onPause時動畫的暫停具则,handler回收消息的移除等這些都與生命周期關(guān)聯(lián)即纲。
- 官方的使用Demo(獲取定位信息)
在App啟動時開啟獲得定位的信息對應(yīng)onStart(),而在onStop()對資源進(jìn)行釋放博肋。
internal class MyLocationListener(
private val context: Context,
private val callback: (Location) -> Unit
) {
fun start() {
//連接到定位服務(wù)器低斋,connect to system location service
}
fun stop() {
//斷開與服務(wù)器的鏈接,disconnect from system location service
}
}
class MyActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(...) {
myLocationListener = MyLocationListener(this) { location ->
//update ui
}
}
public override fun onStart() {
super.onStart()
myLocationListener.start()
}
public override fun onStop() {
super.onStop()
myLocationListener.stop()
}
}
Demo的實現(xiàn)很簡單束昵,但是具有代表性拔稳,比較符合我們以往的“開發(fā)習(xí)慣”葛峻,雖然做到了對生命周期的管理锹雏,在合適的做到了資源的使用與釋放,但是其實是存在問題的术奖。
1.太過于理想化-無論是在
onStart()
還是在onStop()
礁遵,我們都是基于App的生命能夠正常的執(zhí)行的前提之下轻绞,并沒有考慮到異常的情況下如何管理資源;建立在假設(shè)它們能順利執(zhí)行佣耐,對組件MyLocationListener生命周期的管理太過于脆弱政勃。2.一個完整的App肯定包含的組件很多,忽略了其他組件的條件競爭關(guān)系兼砖,其次隨之系統(tǒng)的不斷迭代奸远,方法的疊加,項目會不容易管理就單生命周期這一項工作就很難處理完美讽挟。
3.思考-Glide都不陌生懒叛,在調(diào)用的時候只需要傳入this,內(nèi)部維護(hù)了一套生命周期管理流程耽梅,那么如果MyLocationListener綁定到MyActivity之上這個問題不就解決了嘛薛窥?Lifecycle解決了這個問題支示。
五舵盈、Lifecycle源碼實現(xiàn)
1.Lifecycle
<font color = #0000FF>Defines an object that has an Android Lifecycle. Fragment and FragmentActivity classes implement LifecycleOwner interface which has the getLifecycle method to access the Lifecycle. You can also implement LifecycleOwner in your own classes.</font>
<font color = #0000FF>Lifecycle.Event.ON_CREATE, Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME events in this class are dispatched after the LifecycleOwner's related method returns. Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP, Lifecycle.Event.ON_DESTROY events in this class are dispatched before the LifecycleOwner's related method is called. For instance, Lifecycle.Event.ON_START will be dispatched after onStart returns, Lifecycle.Event.ON_STOP will be dispatched before onStop is called. This gives you certain guarantees on which state the owner is in.</font>
<font color = #0000FF>To observe lifecycle events call addObserver(LifecycleObserver) passing an object that implements either DefaultLifecycleObserver or LifecycleEventObserver.</font>
簡單的概括一下:定義一個具有生命周期的對象。Fragment
與FragmentActivity
實現(xiàn)了LifecycleOwner接口掐松,而接口中方法getLifecycle
可以獲得Lifecycle
引用众旗,開發(fā)者可以通過實現(xiàn)LifecycleOwner接口來自定義自己的生命周期組件罢杉,通過類中狀態(tài),如Lifecycle.Event.ON_START
等完成對應(yīng)的匹配逝钥,要觀察生命周期的事件那么需要通過添加生命周期的觀察者addObserver(LifecycleObserver)
傳遞的是DefaultLifecycleObserver或者LifecycleEventObserver的實現(xiàn)類屑那。
- 注釋中解釋的很清楚,Lifecycle相當(dāng)于一個中轉(zhuǎn)站艘款,有什么作用呢持际?管理生命周期的組件,無論是系統(tǒng)的
Fragment
哗咆、Activity
或者是開發(fā)自定義的組件(實現(xiàn)了LifecycleOwner接口)蜘欲。當(dāng)狀態(tài)流轉(zhuǎn)時,“中轉(zhuǎn)站”內(nèi)的組件的生命周期狀態(tài)應(yīng)該保持對應(yīng)晌柬±逊荩看看源碼中幾個重要的方法:
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();
public enum Event {
ON_CREATE,ON_START,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANY;
@Nullable
public static Event downFrom(@NonNull State state) {
switch (state) {
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
}
}
//......
}
public enum State {
DESTROYED,INITIALIZED,CREATED,STARTED,RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
- 由之前給出的圖,Lifecycle中定義了狀態(tài)State與之對應(yīng)的事件Event年碘,將綁定的生命周期組件添加到中轉(zhuǎn)站之中澈歉,隨著狀態(tài)主體LifecycleOwner狀態(tài)的改變而獲得對應(yīng)的狀態(tài)-
addObserver()
;同樣的有添加就有移除操作removeObserver()
屿衅。也就是說Owner的狀態(tài)發(fā)生改變需要搭配LifecycleObserver才能被轉(zhuǎn)發(fā)下去埃难,典型的觀察與訂閱,首先不看LifecycleObserver具體實現(xiàn)。Lifecycle作為抽象類涡尘,看看其具體實現(xiàn)類忍弛。 - LifecycleRegistry實現(xiàn)類
Lifecycle的具體實現(xiàn)類,用來處理多個LifecycleObserver的狀態(tài)考抄,同時除了Fragment與Activity以外细疚,還可以處理自定義的生命周期組件〈罚看看是如何處理生命周期事件傳遞的疯兼。
public class LifecycleRegistry extends Lifecycle {
//通過一個FastSafeIterableMap將觀察者連同狀態(tài)一起保存起來,保存調(diào)用addObserver()后存儲的對象贫途,這個map
//系統(tǒng)自定義的結(jié)構(gòu)镇防,線程不安全,但是提供了在遍歷時修改的功能潮饱。
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
//當(dāng)前的狀態(tài)
private State mState;
//若引用持用了生命周期的組件
private final WeakReference<LifecycleOwner> mLifecycleOwner;
private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
mEnforceMainThread = enforceMainThread;
}
//設(shè)置當(dāng)前狀態(tài)
@MainThread
public void setCurrentState(@NonNull State state) {
moveToState(state);
}
//處理生命周期事件
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
moveToState(event.getTargetState());
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = 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 sync() {
//省略判空
while (!isSynced()) {
mNewEventOccurred = false;
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;
}
private void forwardPass(LifecycleOwner lifecycleOwner) {
//....
observer.dispatchEvent(lifecycleOwner, event);
//....
}
private void backwardPass(LifecycleOwner lifecycleOwner) {
//...
observer.dispatchEvent(lifecycleOwner, event);
//...
}
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
}
1.在構(gòu)造函數(shù)中来氧,可以看到提供了一個類型為LifecycleOwner的provider,這個很好理解香拉,結(jié)合方法addObserver()啦扬,一個宿主Owner組件中可以包含多個依附的組件,依賴于Owner的生命周期凫碌。只需要觀察這個Owner的狀態(tài)變更作出自身的操作即可扑毡,也即是添加觀察者Observer(LifecycleObserver)。
2.在方法sync()中盛险,首先對目標(biāo)狀態(tài)與當(dāng)前狀態(tài)作了比較瞄摊,方法isSynced(),判斷當(dāng)前狀態(tài)與目標(biāo)是否相等苦掘,并且最新狀態(tài)與最舊的狀態(tài)是否一致换帜,如果都滿足,那么就不會在處理鹤啡。
3.while(!isSynced())中惯驼,也即是狀態(tài)同步,將當(dāng)前狀態(tài)分別與最新递瑰、最舊的狀態(tài)比較保證觀察者的狀態(tài)都是一致的祟牲,如果當(dāng)前狀態(tài)比最舊的狀態(tài)小那么走backwardPass(),反之當(dāng)前狀態(tài)比最新的狀態(tài)大走forwardPass()抖部。以Activity為例说贝,從onStart到onResume經(jīng)歷的事件是很短暫的,這也是為什么取當(dāng)前狀態(tài)的下移狀態(tài)慎颗。
//Returns the Lifecycle.Event that will be reported by a Lifecycle leaving the specified //Lifecycle.State to a higher state, or null if there is no valid event that can move up //from the given state.
public static Event upFrom(@NonNull State state) {
switch (state) {
case INITIALIZED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
default:
return null;
}
}
- dispatchEvent
無論是backwardPass還是forwardPass乡恕,最終都會執(zhí)行到dispatchEvent方法换淆,getTargetState通過計算對應(yīng)的狀態(tài),通知到所有的觀察者几颜。而繼承自LifecycleObserver的LifecycleEventObserver接口方法onStateChanged就完成了狀態(tài)的更新操作。
2.LifecycleOwner
<font color = #0000FF>A class that has an Android lifecycle. These events can be used by custom components to handle lifecycle changes without implementing any code inside the Activity or the Fragment.</font>
具有Android生命周期的類讯屈,通過事件自定義的組件可以處理生命周期的變化而無需在Activity或Fragment中實現(xiàn)相關(guān)代碼蛋哭。
LifecycleOwner是一個接口,僅僅包含了一個方法涮母。返回“生命周期”Lifecycle谆趾。
@SuppressWarnings({"WeakerAccess", "unused"})
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
//The lifecycle of the provider.
}
既然是接口,那么看看實現(xiàn)類叛本,以AppCompatActivity
為例沪蓬,而其完整的繼承鏈路為:
AppCompatActivity -> FragmentActivity -> ComponentActivity
直接查看ComponentActivity
的實現(xiàn)細(xì)節(jié),看看究竟是如何管理生命周期的来候。
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner... {
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// Restore the Saved State first so that it is available to
// OnContextAvailableListener instances
mSavedStateRegistryController.performRestore(savedInstanceState);
mContextAwareHelper.dispatchOnContextAvailable(this);
super.onCreate(savedInstanceState);
//ReportFragment注入
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
}
在ComponentActivity
中僅僅只有一個生命周期方法onCreate()
作了處理跷叉,而其他的生命周期方法并未有具體實現(xiàn)。那又是怎么管理生命周期的呢营搅?跟預(yù)期顯然是不符合的云挟,但是注意到這個ReportFragment這個的注入。似曾相識转质,如果熟悉Glide圖片加載庫對生命周期的管理-無布局的Fragment注入园欣。這里其實也做了同樣的事情⌒菪罚看看是不是使用相似的方法來管理生命周期沸枯。
- ReportFragment
ReportFragment關(guān)鍵代碼實現(xiàn)。
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks()));
}
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
//....
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);
}
}
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
//.....
}
關(guān)鍵方法dispatch()赂弓,ReportFragment通過注入的方法绑榴,依附到Activity之上,根據(jù)Fragment特性盈魁,此時Fragment的生命周期就與宿主Activity綁定了彭沼。對宿主Activity的生命周期的管理自然的就后移到了Fragment之上也就是ReportFragment中。而最終都回調(diào)到了dispatch()之中备埃,到這里就完成了分發(fā)的工作姓惑,那么由誰來真正處理呢?
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
之前提到接口Lifecycle的實現(xiàn)類LifecycleRegistry則是完成了對生命周期的處理按脚。
總結(jié)一下:
1.ReportFragment通過注入的方式依附到Activity之上于毙,將自身的生命周期與Activity綁定,也即是將生命周期的管理后移辅搬。
2.通過dispatch()來分發(fā)生命周期事件唯沮。而最終處理生命周期事件的類則為Lifecycle的實現(xiàn)類-LifecycleRegistry
- 自定義生命周期感知類
官方比較推薦的做法是實現(xiàn)DefaultLifecycleObserver接口
class MyObserver : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
//do something
}
override fun onPause(owner: LifecycleOwner) {
//do something
}
}
myLifecycleOwner.getLifecycle().addObserver(MyObserver())
當(dāng)然也可以配合LifecycleRegistry與LifecycleOwner實現(xiàn)更加細(xì)致的功能需求
class MyActivity : Activity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.markState(Lifecycle.State.CREATED)
}
public override fun onStart() {
super.onStart()
lifecycleRegistry.markState(Lifecycle.State.STARTED)
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}