Lifecycle 的意義:
早期的架構(gòu)中灵寺,生命周期的事件監(jiān)聽和狀態(tài)查詢,需要直接在Activity
/Fragment
的生命周期鉤子中處理区岗。而實(shí)際開發(fā)中略板,往往需要在Activity
/Fragment
外部進(jìn)行事件監(jiān)聽和狀態(tài)查詢。在Lifecycle
引入前慈缔,需要開發(fā)者自定義一套提供偵測功能的Activity/Fragment
基類及回調(diào)接口叮称。
Lifecycle
的引入,即是對以上需求的官方支持藐鹤。類似的瓤檐,在官方推出ViewModels
以前,已經(jīng)存在通過Fragment
實(shí)現(xiàn)相同功能的方案娱节。
Lifecycle 的主要類:
以下基于AndroidX 1.1.0
-
Lifecycle
:
核心抽象類挠蛉。
架構(gòu)的核心,繼承該類的子類肄满,表示本身是一個 具有Android生命周期特性 的對象谴古,能對外提供如下能力:
1.Android生命周期 事件的監(jiān)聽
2.Android生命周期 狀態(tài)的獲取
抽象類內(nèi)部,定義了2個用于生命周期相關(guān)的枚舉類:
1.enum Event
: 生命周期事件
2.enum State
: 生命周期狀態(tài)
LifecycleOwner
:
核心接口稠歉。
顧名思義讥电,該接口的實(shí)現(xiàn)類表示能夠?yàn)橥獠刻峁?code>Lifecycle實(shí)例。
系統(tǒng)框架中轧抗,接口的實(shí)現(xiàn)類為ComponentActivity
和Fragment
,兩者提供的Lifecycle
對象瞬测,是系統(tǒng)框架實(shí)現(xiàn)中Lifecycle
的唯一子類LifecycleRegistry
横媚。-
LifecycleRegistry
:
核心類纠炮。
Lifecycle
子類,系統(tǒng)框架實(shí)現(xiàn)中Lifecycle
的唯一子類灯蝴。
實(shí)現(xiàn)Lifecycle
定義生命周期觀察訂閱恢口,生命周期查詢的方法。還實(shí)現(xiàn)了架構(gòu)中穷躁,生命周期變化時觸發(fā)的自身狀態(tài)處理和相關(guān)對觀察者的訂閱回調(diào)的邏輯耕肩。簡單來說,就是對生命周期持有者提供一組狀態(tài)遷移方法问潭,生命周期持有者在對應(yīng)的生命周期方法中猿诸,增加對這組方法的調(diào)用。而方法調(diào)用后狡忙,
Lifecycle
則會執(zhí)行具體的變換處理梳虽,及執(zhí)行回調(diào)觀察者的邏輯。 -
LifecycleObserver
:
核心接口灾茁。
Lifecycle
架構(gòu)中窜觉,該接口的實(shí)現(xiàn)類表示為關(guān)注生命周期事件的觀察者。
注意的是北专,該接口僅起標(biāo)記實(shí)現(xiàn)類為觀察者的作用禀挫,內(nèi)部不存在任何方法定義。實(shí)際的工作一般根據(jù)需求使用其子類接口或者使用注解實(shí)現(xiàn)拓颓,而主要包括:LifecycleObserver
:
即該接口本身语婴,采用注解方式,@OnLifecycleEvent
標(biāo)記自定義的方法以實(shí)現(xiàn)回調(diào)录粱。
注解的工作方式有兩種:反射腻格,預(yù)編譯適配類,默認(rèn)的工作方式為反射啥繁。
反射方式:
很好理解菜职,就是通過包裝和處理后,最終通過invoke
調(diào)用被注解的方法旗闽。
預(yù)編譯方式:
需要引入注解編譯器:androidx.lifecycle:lifecycle-compiler:<*>
酬核。
對被注解標(biāo)記 且 繼承/實(shí)現(xiàn)LifecycleObserver
接口的 類/接口,自動編譯生成對應(yīng)的繼承GeneratedAdapter
的<ClassName>_LifecycleAdapter.class
適配類适室,以減少反射消耗嫡意,典型的空間換時間。FullLifecycleObserver
:
LifecycleObserver
子接口捣辆。為所有的生命周期事件都定義了對應(yīng)的回調(diào)方法蔬螟。
實(shí)現(xiàn)該接口,就需要把不需要觀察的方法回調(diào)都做一個空實(shí)現(xiàn)汽畴。在沒有java8的default
關(guān)鍵字時旧巾,如果僅需要1-2個回調(diào)方法耸序,那么最終實(shí)現(xiàn)類中的空方法會相當(dāng)?shù)K眼,這種情況下推選使用@OnLifecycleEvent
注解方式替代鲁猩。(當(dāng)然也可以自己弄一個空實(shí)現(xiàn)的BaseLifecycleObserver
)坎怪。DefaultLifecycleObserver
:
FullLifecycleObserver
子接口。使用java8的default
關(guān)鍵字空實(shí)現(xiàn)了FullLifecycleObserver
的所有方法廓握。
需要引入:"androidx.lifecycle:lifecycle-common-java8:<*>
搅窿。
如果項(xiàng)目中使用了java8或者開啟java8特性,那么官方強(qiáng)烈推選DefaultLifecycleObserver
替代的@OnLifecycleEvent
注解實(shí)現(xiàn) (注解后續(xù)可能被棄用)隙券,包括預(yù)編譯男应。
引入DefaultLifecycleObserver
后,就需要把注解實(shí)現(xiàn)相關(guān)邏輯移除是尔。即使保留注解殉了,由于Lifecycling
的處理邏輯(系統(tǒng)架構(gòu)邏輯中所有傳入的觀察者都會經(jīng)過Lifecycling
處理),任何FullLifecycleObserver
的實(shí)現(xiàn)類 (即包括DefaultLifecycleObserver
) 內(nèi)部所有的@OnLifecycleEvent
注解都會失效拟枚。LifecycleEventObserver
:
LifecycleObserver
子接口薪铜。只有一個onStateChanged
方法,以Lifecycle.Event
入?yún)⑻峁┦录^(qū)分的形式恩溅,進(jìn)行統(tǒng)一方法回調(diào)隔箍。
與FullLifecycleObserver
不沖突,但是也會無效化@OnLifecycleEvent
注解脚乡。
同時實(shí)現(xiàn)LifecycleEventObserver
和FullLifecycleObserver
蜒滩,可以得到2次相同的生命周期回調(diào),后者的具體方法回調(diào)優(yōu)先于前者的統(tǒng)一方法回調(diào)奶稠。ReflectiveGenericLifecycleObserver
:
LifecycleEventObserver
子類俯艰。適應(yīng)于注解方式的反射工作方式。
通過該類對觀察者進(jìn)行包裝锌订,處理觀察者關(guān)注的回調(diào)的反射調(diào)用竹握,由Lifecycling
處理包裝過程。SingleGeneratedAdapterObserver
:
LifecycleEventObserver
子類辆飘。適應(yīng)于注解方式的預(yù)編譯工作方式啦辐。
通過該類對觀察者的GeneratedAdapter
進(jìn)行包裝,處理GeneratedAdapter
的方法調(diào)用蜈项,由Lifecycling
處理包裝過程芹关。CompositeGeneratedAdaptersObserver
:
SingleGeneratedAdapterObserver
的復(fù)數(shù)版,內(nèi)部邏輯基本與其一致紧卒,只是提供"復(fù)數(shù)"GeneratedAdapter
的支持侥衬。
怎么理解"復(fù)數(shù)"呢?
首先要知道,在程序運(yùn)行過程轴总,Lifecycling
會查找傳入觀察者自身的對應(yīng)的GeneratedAdapter
贬媒,假如不存在,則會查找其所有父類/接口對應(yīng)的GeneratedAdapter
肘习。
假如存在自身的對應(yīng)的GeneratedAdapter
,那么此時GeneratedAdapter
數(shù)量等于1坡倔,則會實(shí)例化這個GeneratedAdapter
并使用SingleGeneratedAdapterObserver
保存(所以叫做Single)漂佩。
假如目標(biāo)觀察者類自身不包含注解方法,而是繼承或?qū)崿F(xiàn)包含注解方法的LifecycleObserver
類/接口罪塔。根據(jù)前面的預(yù)編譯規(guī)則投蝉,由于目標(biāo)類不包含注解方法,注解編譯器不會為其生成GeneratedAdapter
征堪。
根據(jù)查找邏輯瘩缆,自身對應(yīng)的GeneratedAdapter
不存在,Lifecycling
將會查找其所有父類/接口對應(yīng)的GeneratedAdapter
佃蚜。
如果結(jié)果GeneratedAdapter
數(shù)量等于1庸娱,則走SingleGeneratedAdapterObserver
流程。
如果結(jié)果GeneratedAdapter
數(shù)量大于1 (繼承+實(shí)現(xiàn)谐算,或多實(shí)現(xiàn)等等熟尉,都可能發(fā)生),Lifecycling
將會結(jié)果GeneratedAdapter
實(shí)例化并打包成數(shù)組洲脂,并使用CompositeGeneratedAdaptersObserver
保存(所以叫做Composite)斤儿。 Lifecycling
:
核心工具類。
系統(tǒng)框架實(shí)現(xiàn)中恐锦,對所有LifecycleObserver
的包裝適配器選擇和相關(guān)處理都由本類完成往果。
Lifecycle 的基本使用
使用Lifecycle
基本也就是3個方法:
getLifecycle().addObserver(LifecycleObserver);
getLifecycle().removeObserver(LifecycleObserver);
getLifecycle().getCurrentState();
根據(jù)實(shí)際需求自定義LifecycleObserver
。
Lifecycle 的關(guān)鍵源碼分析:
Lifecycle 與生命周期組件的交互:
雖然ComponentActivity
實(shí)現(xiàn)了LifecycleOwner
接口并持有LifecycleRegistry
實(shí)例一铅,但是操作LifecycleRegistry
生命周期變化的邏輯卻是在ReportFragment
中陕贮。
ComponentActivity
會在初始化階段添加一個ReportFragment
實(shí)例,以此對自身維護(hù)的LifecycleRegistry
進(jìn)行生命周期變化管理馅闽。
androidx.activity 1.0.0-alpha01
引入前飘蚯,LifecycleOwner
由FragmentActivity
實(shí)現(xiàn)。引入后福也,遷移到alpha01中新增的ComponentActivity
局骤。
不直接在ComponentActivity
對LifecycleRegistry
進(jìn)行操作,原因是出于適配考慮暴凑,開發(fā)者有可能直接繼承Activity
峦甩,對這種情況不能直接把Lifecycle
生命周期變化的邏輯直接寫到ComponentActivity
。
ReportFragment 中相關(guān)的注釋 (lifecycle-runtime 2.1.0)
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib,so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully凯傲,we are the first to make a transaction.
manager.executePendingTransactions();
}
}
}
ReportFragment 注入方式
ReportFragment
作為Lifecycle
的實(shí)際操作者犬辰,在ComponentActivity
中通過injectIfNeededIn()
注入:
ComponentActivity (androidx.activity 1.1.0)
public class ComponentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
}
ReportFragment.injectIfNeededIn
把一個ReportFragment
實(shí)例添加到Activity
中:
ReportFragment (lifecycle-runtime 2.1.0)
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
}
ReportFragment 自動注入
上文ReportFragment
的注釋中,提及到了ProcessLifecycleOwner
冰单,但實(shí)際上ProcessLifecycleOwner
也需要依賴ReportFragment
的生命周期監(jiān)聽特性幌缝。真正實(shí)現(xiàn)自動注入ReportFragment
的類是LifecycleDispatcher
。
ProcessLifecycleOwner
及LifecycleDispatcher
需要引入androidx.lifecycle:lifecycle-process:<*>
或android.arch.lifecycle:extensions:<*>
诫欠。
后者中所有API在2.2.0版本中完全被拆分涵卵,并被棄用及停止維護(hù)。一般建議根據(jù)具體功能引入具體的庫荒叼。
當(dāng)LifecycleDispatcher.init
被調(diào)用時轿偎,將會通過Application.registerActivityLifecycleCallbacks
添加全局的Activity
生命周期鉤子,并在Activity.onCreated
時向其注入ReportFragment
被廓。
LifecycleDispatcher (lifecycle-process 2.2.0)
class LifecycleDispatcher {
static void init(Context context) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.injectIfNeededIn(activity);
}
}
}
LifecycleDispatcher.init
被ProcessLifecycleOwnerInitializer
調(diào)用坏晦,原理是基于ContentProvider
會跟隨Application
的創(chuàng)建而創(chuàng)建的特性,自動獲取Application
嫁乘,而無需開發(fā)者顯示初始化昆婿。
這個技巧在很多框架中都有使用,例如Picasso中的
PicassoProvider
亦渗。
ProcessLifecycleOwnerInitializer (lifecycle-process 2.2.0)
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
}
Manifest 中自動注冊 ProcessLifecycleOwnerInitializer
<manifest>
<application>
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
android:exported="false"
android:multiprocess="true"
android:authorities="com.example.jetpacklearn.lifecycle-process" />
</application>
</manifest>
這里有個坑挖诸,SDK Manager下載的API28 Source中包含了
AndroidX
的相關(guān)源碼,注意分析的不要弄錯源碼位置法精。
ReportFragment 與 Lifecycle 的交互
ReportFragment
會在偵測到Activity
生命周期變化的時候調(diào)用LifecycleRegistry.handleLifecycleEvent()
傳入對應(yīng)的狀態(tài)多律。
在不同版本, ReportFragment
對Activity
的偵測方法實(shí)現(xiàn)有所不同。
API28及以下:
主要是通過ReportFragment
將自身添加到Activity
中實(shí)現(xiàn)搂蜓。
ReportFragment (lifecycle-runtime 2.1.0)
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
// 嘗試獲取 Activity 中的 LifecycleRegistry 并調(diào)用 handleLifecycleEvent
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
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);
}
}
}
// 各個生命周期鉤子中狼荞,調(diào)用 dispatch
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
}
API29:
Activity
中增加一組ActivityLifecycleCallbacks
的相關(guān)方法,可以直接通過注冊ActivityLifecycleCallbacks
觀察生命周期帮碰。而該版本的ReportFragment
則把生命周期偵測方案遷移到ActivityLifecycleCallbacks
形式相味。
為了前向兼容,ReportFragment
依然會被添加到Activity
殉挽,并在dispatch()
中增加過濾避免出現(xiàn)二次調(diào)用阅酪。
ReportFragment (lifecycle-runtime 2.2.0)
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}
// Prior to API 29 and to maintain compatibility with older versions of
// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
// need to support activities that don't extend from FragmentActivity from support lib),
// use a framework fragment to get the correct timing of Lifecycle events
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 class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
// ActivityLifecycleCallbacks的各個生命周期鉤子中秧了,調(diào)用 dispatch
@Override
public void onActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
dispatch(activity, Lifecycle.Event.ON_CREATE);
}
......
}
// 2.1.0 及之前版本調(diào)用的方法
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
// Only dispatch events from ReportFragment on API levels prior
// to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
// added in ReportFragment.injectIfNeededIn
dispatch(getActivity(), event);
}
}
// 2.2.0 新增的 dispatch 重載
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);
}
}
}
}
至此,生命周期組件對
LifecycleRegistry
的調(diào)用已分析完成,接下來就是分析LifecycleRegistry
如何管理自身的生命周期狀態(tài)敷搪,及如何回調(diào)到開發(fā)者注冊的觀察者屡拨。
LifecycleRegistry (基于lifecycle-runtime 2.2.0)
在開始分析LifecycleRegistry
前湃崩,需要了解下面的設(shè)計(jì)點(diǎn)惶我。
不變式
在LifecycleRegistry
中承耿,傳入的Observer
通過鏈表mObserverMap
保存,鏈表存在一個不變式:
根據(jù)添加順序伪煤,鏈表中的任意節(jié)點(diǎn)(Observer
)加袋,對應(yīng)的狀態(tài)State
,始終大于等于后驅(qū)節(jié)點(diǎn)的狀態(tài)抱既。
該不變式在影響到整個源碼的邏輯實(shí)現(xiàn)职烧,所以需要優(yōu)先了解。
/**
* Custom list that keeps observers and can handle removals / additions during traversal.
*
* Invariant: at any moment of time for observer1 & observer2:
* if addition_order(observer1) < addition_order(observer2), then
* state(observer1) >= state(observer2),
*/
private FastSafeIterableMap mObserverMap = new FastSafeIterableMap<>();
狀態(tài)與事件
Lifecycle
的生命狀態(tài)狀態(tài)并沒有精確到對應(yīng)每個生命周期事件防泵,例如onPause->onStop不存在對應(yīng)的STOPED狀態(tài)阳堕,而是STARTED。狀態(tài)遷移時择克,需要通過升降級方向,計(jì)算出對應(yīng)觸發(fā)的生命周期事件前普。例如當(dāng)前RESUMED
肚邢,降級到STARTED
,則對應(yīng)事件onPause
拭卿。
生命周期狀態(tài)的數(shù)值對比:
DESTROYED
< INITIALIZED
< CREATED
< STARTED
< RESUMED
基于狀態(tài)等級的相關(guān)方法:
// 計(jì)算事件發(fā)生后, 將會遷移到的狀態(tài)
static State getStateAfter(Event event) {...}
// 計(jì)算傳入狀態(tài)降級所對應(yīng)的事件
private static Event downEvent(State state) {...}
// 計(jì)算傳入狀態(tài)升級所對應(yīng)的事件
private static Event upEvent(State state) {...}
// 獲取兩個狀態(tài)中的較小值
static State min(@NonNull State state1, @Nullable State state2) {...}
狀態(tài)和事件可以參考下圖:
LifecycleRegistry 成員變量:
-
mObserverMap
:
Observer
列表骡湖,采用FastSafeIterableMap
,key為Observer
峻厚,value為對Observer
的封裝對象ObserverWithState
响蕴。ObserverWithState
在持有Observer
的同時,保存了Observer
對應(yīng)的狀態(tài)惠桃。LiveData
也是類似的實(shí)現(xiàn)浦夷。FastSafeIterableMap
是SafeIterableMap
的子類,本質(zhì)并不是java.util.Map
的實(shí)現(xiàn)類辜王。
SafeIterableMap
內(nèi)部是通過自定義Entry<K, V>
實(shí)現(xiàn)的鏈表劈狐,通過遍歷Entry
對比Key值存取Value
實(shí)現(xiàn)的類似LinkedHashMapEntry
的Map,是一個使用場景比較狹窄的容器呐馆,非線程安全肥缔,支持在遍歷的過程中刪除任意元素。
可以參考:SafeIterableMap:一個能在遍歷中刪除元素的數(shù)據(jù)結(jié)構(gòu)
而FastSafeIterableMap
可以說是LifecycleRegistry
的專用容器汹来,是在SafeIterableMap
的基礎(chǔ)上增加一個HashMap記錄<Key,Entry<K, V>>
续膳,主要是提供了contains()
快速判斷是否存在對應(yīng)的Key,以及ceil()
查找目標(biāo)Key對應(yīng)的Entry<K, V>
的前結(jié)點(diǎn)的能力收班。 mState
:
當(dāng)前LifecycleRegistry
的生命周期狀態(tài)坟岔。mLifecycleOwner
:
當(dāng)前對應(yīng)的生命周期提供者,使用弱引用防止內(nèi)存泄漏闺阱。mAddingObserverCounter
:
記錄正在初始化同步的新添加Observer
的數(shù)量炮车,大于0時,表示正在對新添加的Observer
進(jìn)行初始化同步。
防止addObserver()
重入時瘦穆,多次調(diào)用sync()
纪隙。使sync()
僅僅在最外層的addObserver()
同步邏輯完成后執(zhí)行一次。mHandlingEvent
:
標(biāo)記正在進(jìn)行狀態(tài)事件同步扛或。
防止moveToState()
重入時绵咱,多次調(diào)用sync()
。mNewEventOccurred
:
標(biāo)記發(fā)生事件嵌套熙兔。
主要作用在moveToState()
重入時悲伶,將mNewEventOccurred
設(shè)置為true
,打斷正在發(fā)生的sync()
同步邏輯住涉,并重新執(zhí)行麸锉。mParentStates
:
用于解決addObserver()
過程中可能發(fā)生的remove
+add
,保證鏈表的不變式成立舆声。
從上可以分析出花沉,LifecycleRegistry
的存在兩種同步邏輯:
- 對新添加的
Observer
進(jìn)行初始化同步,在添加Observer
時調(diào)用addObserver()
觸發(fā)媳握。 - 對所有
Observer
進(jìn)行狀態(tài)事件同步碱屁,在生命周期事件遷移中調(diào)用sync()
觸發(fā)。
并且LifecycleRegistry
在設(shè)計(jì)時蛾找,對同步過程中可能發(fā)生重入進(jìn)行了支持娩脾。
ObserverWithState 靜態(tài)內(nèi)部類:
對傳入的Observer
進(jìn)行封裝,通過Lifecycling
轉(zhuǎn)為統(tǒng)一的LifecycleEventObserver
對象打毛,并同時保存對應(yīng)的mState
狀態(tài)柿赊。
static class ObserverWithState {
// 當(dāng)前狀態(tài)
State mState;
// observer封裝
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
// 這里就是上文提及到的Lifecycling對observer進(jìn)行適配
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
// 封裝的事件派分邏輯
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
LifecycleRegistry 方法:
生命周期操作方法
生命周期操作方法有2個, 分別是
-
setCurrentState(State state)
:遷移到傳入的指定狀態(tài) -
handleLifecycleEvent(Lifecycle.Event event)
:遷移到傳入事件發(fā)生后對應(yīng)的狀態(tài)
兩者的內(nèi)部,實(shí)際調(diào)用的方法為moveToState()
幻枉。
public class LifecycleRegistry extends Lifecycle {
public void setCurrentState(@NonNull State state) {
moveToState(state);
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
}
moveToState(State next)
:
將LifecycleRegistry
設(shè)置到對應(yīng)的傳入狀態(tài)next
闹瞧,并觸發(fā)sync()
進(jìn)行狀態(tài)事件同步。
private void moveToState(State next) {
// 狀態(tài)沒有發(fā)生遷移時, 直接返回不進(jìn)行處理
if (mState == next) {
return;
}
// 記錄當(dāng)前狀態(tài)為傳入狀態(tài)
mState = next;
// 檢查moveToState是否重入
// 檢查addObserver是否重入
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
// 標(biāo)記開始狀態(tài)事件同步
mHandlingEvent = true;
// 同步新狀態(tài)事件
sync();
// 移除狀態(tài)事件同步標(biāo)記
mHandlingEvent = false;
}
sync()
:
同步新狀態(tài)到所有保存的Observer
展辞。
while循環(huán)通過isSynced()
判斷是否完成同步奥邮,嘗試使用backwardPass()
和backwardPass()
進(jìn)行同步操作直到同步完成,前者處理前臺到銷毀的過程罗珍,后者則相反洽腺。
private void sync() {
// 同步時,假如生命周期組件已回收覆旱,拋出異常
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("...");
}
// 循環(huán)蘸朋,直到isSynced判斷同步完成
while (!isSynced()) {
// 移除新事件標(biāo)記
mNewEventOccurred = false;
// 頭節(jié)點(diǎn)狀態(tài)大于當(dāng)前狀態(tài),降級同步
// 例:RESUMED->STARTED
// 不用對頭結(jié)點(diǎn)做非空判斷扣唱,因?yàn)轭^結(jié)點(diǎn)不存在時藕坯,isSynced返回true
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
// 尾節(jié)點(diǎn)狀態(tài)小于當(dāng)前狀態(tài)团南,升級同步
// 例:STARTED->RESUMED
// 需要檢測mNewEventOccurred,降級同步時有可能發(fā)生事件嵌套
// 需要對尾節(jié)點(diǎn)作出空判斷炼彪,降級同步時有可能將節(jié)點(diǎn)移除吐根,
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
// 移除新事件標(biāo)記
mNewEventOccurred = false;
}
isSynced()
:
判斷是否已經(jīng)完成同步。
當(dāng)mObserverMap
首尾節(jié)點(diǎn)狀態(tài)相同辐马,且尾節(jié)點(diǎn)狀態(tài)等于當(dāng)前狀態(tài)時拷橘,認(rèn)為同步完成。
private boolean isSynced() {
// 假如不存在觀察者喜爷,則不需要同步冗疮,返回已同步
if (mObserverMap.size() == 0) {
return true;
}
// 尾節(jié)點(diǎn)狀態(tài)和頭節(jié)點(diǎn)狀態(tài)相同,且等于當(dāng)前狀態(tài)檩帐,則已同步
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
backwardPass(LifecycleOwner lifecycleOwner)
:
降級同步术幔,同步過程優(yōu)先進(jìn)行降級同步。
為確保不變式湃密,mObserverMap
的遍歷從尾部指向頭部特愿,優(yōu)先減少尾節(jié)點(diǎn)的狀態(tài)值,通過descendingIterator()
構(gòu)建逆向的迭代器實(shí)現(xiàn)勾缭。
private void backwardPass(LifecycleOwner lifecycleOwner) {
// 逆向迭代器,源碼比較簡單目养,此處不貼出
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
// 通過迭代器遍歷俩由,遇到新事件標(biāo)識時中斷
while (descendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
// 循環(huán)對比單個觀察者的狀態(tài),直到單個觀察者同步到目標(biāo)狀態(tài)
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
// 獲取狀態(tài)對應(yīng)的事件
Event event = downEvent(observer.mState);
// 緩存observer的狀態(tài)癌蚁,用于remove+add問題
pushParentState(getStateAfter(event));
// 派分事件
observer.dispatchEvent(lifecycleOwner, event);
// 移除observer狀態(tài)緩存
popParentState();
}
}
}
forwardPass(LifecycleOwner lifecycleOwner)
和backwardPass()
類似幻梯,只是迭代器正向遍歷,鏈表頭部優(yōu)先升級努释,以確保不變式成立碘梢。
至此可以了解到,
LifecycleRegistry
如何在生命周期改變時伐蒂,外部通過setCurrentState()
和handleLifecycleEvent()
煞躬,最終調(diào)用moveToState()
執(zhí)行新狀態(tài)設(shè)置和Observe
同步。
基于不變式逸邦,升級時Observe
先進(jìn)先同步恩沛,降級時Observe
后進(jìn)先同步。
addObserver(LifecycleObserver observer)
:
通過addObserver()
將Observer
添加到LifecycleRegistry
缕减。
Observer
在添加過程中雷客,會優(yōu)先被初始化同步到一個最小狀態(tài),這個狀態(tài)通過calculateTargetState()
獲取桥狡。
calculateTargetState()
:
主要是對比當(dāng)前LifecycleRegistry
的狀態(tài)搅裙、Observer
鏈表的尾節(jié)點(diǎn)及mParentStates
的最后一個元素皱卓,取出其中的最小值。
private State calculateTargetState(LifecycleObserver observer) {
Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
State siblingState = previous != null ? previous.getValue().mState : null;
State parentState = !mParentStates.isEmpty() ?
mParentStates.get(mParentStates.size() - 1) : null;
return min(min(mState, siblingState), parentState);
}
繼續(xù)分析addObserver()
方法部逮。
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// 獲取的observer需要設(shè)置的初始狀態(tài)
// 假如當(dāng)前狀態(tài)為DESTROYED則設(shè)置為DESTROYED, 否則設(shè)置為INITIALIZED
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 通過ObserverWithState對observer進(jìn)行包裝娜汁,并綁定初始的生命周期狀態(tài)
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 將包裝的observer添加到mObserverMap,以observer自身作為Key值
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
// 假如observer已添加甥啄,不進(jìn)行后續(xù)操作
if (previous != null) {
return;
}
// 假如lifecycleOwner已銷毀存炮,不進(jìn)行后續(xù)操作
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
return;
}
// 判斷是否重入,重入有2個指標(biāo)
// mHandlingEvent表示正在執(zhí)行生命周期遷移導(dǎo)致的sync()同步
// mAddingObserverCounter>0 表示addObserver()導(dǎo)致的單個Observer同步
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
// 通過calculateTargetState獲取當(dāng)前目標(biāo)需要遷移的目標(biāo)狀態(tài)
State targetState = calculateTargetState(observer);
// 正在添加Observer的記錄自增
mAddingObserverCounter++;
// 使Observer遷移到目標(biāo)狀態(tài)
//
// 當(dāng)Observer的狀態(tài)小于目標(biāo)狀態(tài)時蜈漓,升級到目標(biāo)狀態(tài)
// Observer的初始狀態(tài)時DESTROYED或INITIALIZED穆桂,且當(dāng)初始狀態(tài)為DESTROYED時,目標(biāo)狀態(tài)
// 也應(yīng)為DESTROYED融虽,所以新添加的Observer在初始化同步的時候只需要考慮升級同步享完。
//
// 這里同時做了mObserverMap.contains(observer)的判斷,之所以要這么處理有额,是因?yàn)橛袝r候
// 用戶會在observer的生命周期回調(diào)中removeObserver移除自身般又,當(dāng)發(fā)生這種情況時,立即結(jié)束
// 遷移操作
while ((statefulObserver.mState.compareTo(targetState) < 0 &&
mObserverMap.contains(observer))) {
// 緩存observer的狀態(tài)巍佑,用于remove+add問題
pushParentState(statefulObserver.mState);
// 派分事件
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
// 移除狀態(tài)緩存
popParentState();
// 由于可能存在的變更茴迁,重新調(diào)用calculateTargetState獲取當(dāng)前目標(biāo)需要遷移的目標(biāo)狀態(tài)
targetState = calculateTargetState(observer);
}
// 非重入狀態(tài)執(zhí)行sync同步
if (!isReentrance) {
sync();
}
// 正在添加Observer的記錄自減
mAddingObserverCounter--;
}
至此,完成對
addObserver()
在添加Observer
時萤衰,進(jìn)行初始化同步的分析堕义。
重入問題:
LifecycleRegistry
設(shè)計(jì)了mAddingObserverCounter
,mHandlingEvent
脆栋,mNewEventOccurred
倦卖,主要是確保sync()
只在最頂層執(zhí)行同步,以免出現(xiàn)同步錯誤椿争。
在調(diào)用sync()
之前怕膛,通過判斷mAddingObserverCounter != 0
或mHandlingEvent
判斷sync()
是否需要執(zhí)行:
-
mHandlingEvent = true
:
表示正在進(jìn)行狀態(tài)事件同步,此時sync()
正在執(zhí)行秦踪,無需再次調(diào)用褐捻。moveToState(state1) -> sync() -> moveToState(state2) -> sync() // 無需執(zhí)行 moveToState(state1) -> sync() -> addObserver() -> sync() // 無需執(zhí)行
-
mNewEventOccurred != 0
:
表示正在進(jìn)行Observer
初始化同步,在同步結(jié)束時會調(diào)用sync()
椅邓,無需在同步內(nèi)部調(diào)用舍扰。addObserver() -> addObserver() -> sync() // 無需執(zhí)行 -> sync() addObserver() -> moveToState(state1) -> sync() // 無需執(zhí)行 -> sync()
remove+add問題:
在源碼中存在注釋說明:
// we have to keep it for cases:
// void onStart() {
// mRegistry.removeObserver(this);
// mRegistry.add(newObserver);
// }
// newObserver should be brought only to CREATED state during the execution of
// this onStart method. our invariant with mObserverMap doesn't help, because parent observer
// is no longer in the map.
private ArrayList<State> mParentStates = new ArrayList<>();
假如Observer
鏈表中僅存在一個Observer1
,這個Observer
在onStart()
中希坚,從鏈表中移除边苹,且添加一個新的Observer2
。
在onStart()
回調(diào)執(zhí)行過程中裁僧,實(shí)際上Observer1
的狀態(tài)還沒轉(zhuǎn)變?yōu)?code>STARTED个束,而是還處在CREATED
:
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
// 先執(zhí)行回調(diào) Event = ON_START
mLifecycleObserver.onStateChanged(owner, event);
// 再設(shè)置狀態(tài) mState = STARTED
mState = newState;
}
在onStart()
中慕购,Observer1
從鏈表中移除,添加Observer2
茬底。Observer2
執(zhí)行初始化同步沪悲,同步的目標(biāo)狀態(tài)通過calculateTargetState()
獲取,假如不引入mParentStates
阱表,將會使Observer2
直接同步到STARTED
:
private State calculateTargetState(LifecycleObserver observer) {
// 由于Observer1已移除殿如,previous == null
Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
// previous == null 導(dǎo)致 siblingState == null
State siblingState = previous != null ? previous.getValue().mState : null;
// 由于siblingState == null, min()返回mState,即STARTED
return min(mState, siblingState);
}
此時會導(dǎo)致Observer2
優(yōu)先Observer1
進(jìn)入STARTED
狀態(tài)最爬,破壞了鏈表的有序性涉馁。引入mParentStates
,就是為了解決以上的情況爱致。由于mParentStates
緩存了Observer1
的值烤送,即使Observer1
從鏈表中移除,依然能從mParentStates
中獲取糠悯,防止后續(xù)添加的Observer2
初始化同步越界帮坚。
private State calculateTargetState(LifecycleObserver observer) {
...
// 緩存值為CREATED
State parentState = !mParentStates.isEmpty() ?
mParentStates.get(mParentStates.size() - 1): null;
// 相當(dāng)于 min(STARTED, CREATED), 返回CREATED
return min(min(mState, siblingState), parentState);
}
Fragment的LifeCycle
AndroidX提供的Fragment
(androidx.fragment.app
)實(shí)現(xiàn)了LifecycleOwner
接口,支持通過getLifecycle()
獲取Lifecycle
互艾,進(jìn)行生命周期事件偵測试和。
處理邏輯基本和ReportFragment
相同,即在對應(yīng)的生命周期會調(diào)用調(diào)用對應(yīng)的操作方法纫普。
Fragment (androidx.fragment 1.1.0)
/**
* ...
* The main differences when using this support version instead of the framework version are:
* <ul>
* <li>Your activity must extend {@link FragmentActivity}
* <li>You must call {@link FragmentActivity#getSupportFragmentManager} to get the
* {@link FragmentManager}
* </ul>
*/
public class Fragment implements LifecycleOwner, ... {
// 創(chuàng)建 LifecycleRegistry 相關(guān)
LifecycleRegistry mLifecycleRegistry;
public Fragment() {
initLifecycle();
}
private void initLifecycle() {
mLifecycleRegistry = new LifecycleRegistry(this);
}
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
// 調(diào)用示例
void performCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState);
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
}
FragmentActivity
的生命周期方法中阅悍,通過FragmentController
、FragmentManagerImpl
局嘁,最終調(diào)用Fragment
中相應(yīng)的生命周期方法。
由于涉及的源碼數(shù)量較多且比較簡單晦墙,此處不貼出源碼悦昵。
回調(diào)順序
需要注意的是,除了onCreate()
晌畅、onResume()
外但指,FragmentActivity
對FragmentController
的調(diào)用發(fā)生在相應(yīng)的生命周期內(nèi),所以Fragment
的生命周期回調(diào)(包括Observer
)會比開發(fā)者定義的邏輯(super.onXXX()
之后及Observer
)優(yōu)先:
class Activity {
final void performStart(String reason) {
// 調(diào)用 Activity.onStart()
mInstrumentation.callActivityOnStart(this);
// ReportFragment onStart (2)
mFragments.dispatchStart();
}
}
class FragmentActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Fragment onStart (1)
mFragments.dispatchCreate();
}
}
onCreate()
FragmentActivity.onCreate()
中抗楔,super.onCreate()
發(fā)生在mFragments.dispatchCreate()
之前:
class FragmentActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Fragment onCreate (2)
mFragments.dispatchCreate();
}
}
class Activity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
// ReportFragment onStart (1)
mFragments.dispatchCreate();
}
}
onResume()
為了對舊版本的適配棋凳,FragmentActivity
沒有在onResume()
中調(diào)用mFragments.dispatchResume()
,而是延遲到super.onPostResume()
之后连躏。
class FragmentActivity {
/**
* Dispatch onResume() to fragments. Note that for better inter-operation
* with older versions of the platform, at the point of this call the
* fragments attached to the activity are <em>not</em> resumed.
*/
protected void onResume() {
super.onResume();
}
/**
* Dispatch onResume() to fragments.
*/
protected void onPostResume() {
super.onPostResume();
onResumeFragments();
}
/**
* This is the fragment-orientated version of {@link #onResume()} that you
* can override to perform operations in the Activity at the same point
* where its fragments are resumed. Be sure to always call through to
* the super-class.
*/
protected void onResumeFragments() {
// Fragment onResume (2)
mFragments.dispatchResume();
}
}
class Activity {
final void performResume(boolean followedByPause, String reason) {
// ReportFragment onResume (1)
mFragments.dispatchResume();
}
}
更具體的邏輯可以自行閱讀 ActivityThread
剩岳,Instrumentation
以及Activity
的源碼。
FragmentActivity.mFragmentLifecycleRegistry
基于Fragment-1.1.0入热,暫時還沒有實(shí)際用于(或者我沒發(fā)現(xiàn)拍棕,官方文檔也沒有發(fā)現(xiàn)提及相關(guān)的修改)晓铆。根據(jù)TODO的說明,后續(xù)應(yīng)該會用于管理Fragment
的LifecycleRegistry
對象绰播。
class FragmentActivity {
/**
* A {@link Lifecycle} that is exactly nested outside of when the FragmentController
* has its state changed, providing the proper nesting of Lifecycle callbacks
* <p>
* TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
*/
final LifecycleRegistry mFragmentLifecycleRegistry =
new LifecycleRegistry(this);
}
以上即為Lifecycle
的分析骄噪。
水平有限,如有錯誤蠢箩,歡迎指正链蕊。