在21年時候有寫過一次lifecycle: http://www.reibang.com/p/838631cdf520骂际。時隔兩三年了剛好最近在看jetpack相關(guān)的一些庫谍椅。回顧下lifecycle實(shí)現(xiàn)源碼. 現(xiàn)在再來看感受又不一樣凳厢,之前可能注重他的流程◎蛎現(xiàn)在更多關(guān)注他的實(shí)現(xiàn)細(xì)節(jié)和為什么這么設(shè)計(jì)碎罚,這樣設(shè)計(jì)的好處是什么欣硼,可能多些自己的思考吧混卵。
1.總體的流程
lifecycle 整個實(shí)現(xiàn)基于觀察者模式映穗,比如我們activity就是被觀察者,我們自己定義一個觀察者 通過addObserver方法 傳入觀察者幕随,把觀察者對象保存在緩存Map中蚁滋,而在componentActivty中 關(guān)聯(lián)了Actiivty生命周期(29以上Activity LifecycleCallbacks生命周期回調(diào)或者空fragment實(shí)現(xiàn)。 內(nèi)部維護(hù)了5個狀態(tài)和6個事件赘淮,來保證觀察者 被觀察者的狀態(tài)一致辕录,如果不一致會觸發(fā)執(zhí)行sync方法從當(dāng)前被觀察者的狀態(tài)獲取事件,觀察者分發(fā)調(diào)用事件梢卸,觸發(fā)onstateChange方法反射調(diào)用觀察者不同的注解生命周期方法走诞。
2.源碼實(shí)現(xiàn)
大部分源碼在上一篇已經(jīng)有了,這里主要補(bǔ)充一下新版本特性和一些細(xì)節(jié)
2.1.被觀察者
Lifecycle是一個接口低剔,里面定義了addObsever()速梗、removeObserver肮塞、兩個枚舉State、Event以及根據(jù)Event獲取State姻锁、根據(jù)State獲取Event的方法 整個框架要用的都定義在里面枕赵。實(shí)現(xiàn)類是LifecycleRegistry
1.androidx的默認(rèn)Activity繼承了ComponentActivity,而ComponentActivity實(shí)現(xiàn)了LifeCycleOwner接口
public class ComponentActivity extends Activity implements
LifecycleOwner,
LifecycleOwner接口里面只提供了getLifecycle方法
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
也正是因?yàn)樘峁┝诉@個方法,他的實(shí)現(xiàn)類可以直接調(diào)用這個方法位隶,看componentActivity的實(shí)現(xiàn)是:
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
return mLifecycleRegistry;
Fragment 類似的也實(shí)現(xiàn)了LifecycleOwner接口:
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, SavedStateRegistryOwner {
完成基本介紹后 我們直接看重點(diǎn)ComponentActivity中的onCreate方法:
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
ReportFragment目的就是參考Glide框架添加一個沒有UI的fragment到activity上拷窜,通過FragmentManager關(guān)聯(lián),在Activity源碼中也能看到生命周期變化會調(diào)用FragmentController去dispatch對應(yīng)fragment生命周期函數(shù).
看到添加方法實(shí)現(xiàn)如下涧黄,判斷版本是否大于29:
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
LifecycleCallbacks.registerIn(activity);
}
// 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();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
根據(jù)版本判斷api29以上注冊ActivityLifecycleCallbacks回調(diào)監(jiān)聽生命周期篮昧,以下的版本添加fragment關(guān)聯(lián)生命周期。主要為了兼容高低版本生命周期變化笋妥。
`
最終都會調(diào)用 dispatch(activity, Lifecycle.Event.ON_XXX)懊昨;區(qū)別是29以上在回調(diào)里面調(diào)用,29以下是在ReportFragment生命周期方法中調(diào)用
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);
}
}
}
核心代碼調(diào)用handleLifecycleEvent 里面又調(diào)用
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
這里需要注意的是第一個mState == next 判斷春宣,也就是觀察者lifecycle的狀態(tài)和被觀察者activit的狀態(tài)如果是一樣的酵颁,直接不執(zhí)行后續(xù)邏輯,也就不會觸發(fā)觀察者的生命周期方法月帝,
主要還是保證觀察者被觀察者狀態(tài)一致躏惋,如果不一致則對mstate賦值,再調(diào)用sync方法
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
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;
}
里面代碼也比較清晰嚷辅,如果觀察者被觀察者狀態(tài)不一致一致執(zhí)行循環(huán)保證一致簿姨,不一致則比較誰的狀態(tài)值大,分別狀態(tài)遷移 后移簸搞。
Event event = Event.downFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event down from " + observer.mState);
}
pushParentState(event.getTargetState());
observer.dispatchEvent(lifecycleOwner, event);
里面其實(shí)是根據(jù)當(dāng)前的狀態(tài)扁位,取出事件類型再調(diào)用observer的分發(fā)事件 來保持狀態(tài)一致。而分發(fā)事件攘乒,核心代碼是下面的:
mLifecycleObserver.onStateChanged(owner, event);
onStateChanged接口方法的實(shí)現(xiàn)是初始化時候addObsever()時候保存的觀察者信息類到
ReflectiveGenericLifecycleObserver
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
target);
}
里面用到線程安全的map,key是觀察者贤牛,value是包裝后的對象里面保存了觀察者和初始狀態(tài)
再通過反射調(diào)用觀察者的對應(yīng)注解的方法
3.思考和總結(jié)
1.為什么涉及mActive變量?
格局出發(fā)则酝,mActive設(shè)計(jì)不知給自己用殉簸,還為了給別的框架用。lifecycle雖然是一個組件沽讹,更多的是他結(jié)合liveData viewModle等一起用般卑,比如liveData在mActive為onStart、onResume才執(zhí)行一些邏輯 否則直接過濾爽雄,保證了一些場景安全蝠检,頁面都關(guān)了網(wǎng)絡(luò)請求回來刷新數(shù)據(jù)。
2.為什么要把狀態(tài)涉及為復(fù)用的挚瘟?
個人猜測是為了減少狀態(tài)的值少兩個叹谁,同時區(qū)分開Activity的本身狀態(tài)饲梭。如果定義了和Activit生命周期一樣的狀態(tài),感覺會比較重復(fù)焰檩,但是又為了記錄當(dāng)前狀態(tài)憔涉。
3.里面設(shè)計(jì)思想?設(shè)計(jì)模式析苫?
源碼里面真的是大量使用設(shè)計(jì)模式兜叨,這里用到觀察者模式、建造者模式衩侥、享元国旷、裝飾、模版方法茫死、工廠跪但、單例很多都涉及到了。不一一舉例峦萎。
4.ReportFragment的injectIfNeededIn方法為什么要區(qū)分29以上版本
API 29 或以上版本進(jìn)行區(qū)分的原因主要在于 Android 對 Fragment 的管理和生命周期有所變化
以前的版本中特漩,ReportFragment 需要用老的 android.app.Fragment 來保證與老的 lifecycle-runtime 的兼容性。
從 API 29 開始骨杂,Android 引入了新的 Fragment API(androidx.fragment.app.Fragment),并且對 Fragment 生命周期進(jìn)行了優(yōu)化雄卷,當(dāng) Activity 調(diào)用 onStop 時搓蚪,F(xiàn)ragment 的 onStop 會先于 Activity 的 onStop 被調(diào)用,這樣就可以在 Fragment 中更早地保存狀態(tài)丁鹉。而在 API 29 之前妒潭,F(xiàn)ragment 的 onStop 是在 Activity 的 onStop 之后調(diào)用的。
5.使用場景如何揣钦,用起來是否方便
一般結(jié)合LiveData viewModle使用雳灾,上家公司也直接結(jié)合MVP模式管理生命周期防止業(yè)務(wù)開發(fā)同學(xué)忘記手動釋放資源。