一文搞懂Android JetPack組件原理之Lifecycle禀梳、LiveData承璃、ViewModel與源碼分析技巧

原文鏈接:https://www.androidos.net.cn/doc/2020/9/26/478.html

好文推薦

前言

Lifecycle利耍、LiveData和ViewModel作為AAC架構(gòu)的核心,常常被用在Android業(yè)務(wù)架構(gòu)中。在京東商城Android應(yīng)用中隘梨,為了事件傳遞等個性化需求程癌,比如ViewModel間通信、ViewModel訪問Activity等等轴猎,以及為了架構(gòu)的擴(kuò)展性席楚,我們封裝了BaseLiveData和BaseViewModel等基礎(chǔ)組件,也對Activity税稼、Fragement和ViewHolder進(jìn)行了封裝烦秩,以JDLifecycleBaseActivity、LifecycleBaseFragment和LifecycleBaseViewHolder等組件強(qiáng)化了View層功能郎仆,構(gòu)建出了各業(yè)務(wù)線統(tǒng)一規(guī)范架構(gòu)的基石只祠。

在開發(fā)過程中,我們有時還會對它們的原理細(xì)節(jié)有些疑惑扰肌,比如會有Lifecycle會不會對性能造成影響抛寝、LiveData為什么是粘性事件的、ViewModel的生命周期是什么樣的等等問題曙旭,這些問題或多或少會對我們的日常開發(fā)和協(xié)作造成影響盗舰,所以對這些組件的源碼分析就變得很有必要,而掌握一些分析方法更能提高效率桂躏。本文就以Lifecycle钻趋、LiveData和ViewModel三大組件的源碼分析為例,探討一下分析方法和技巧剂习,整體目錄如下圖所示蛮位,希望能給大家?guī)硎斋@。

源碼下載

官方地址:https://android.googlesource.com/platform/frameworks/support/或Github:https://github.com/androidx/androidx鳞绕,以上都列出了比較詳細(xì)的下載步驟和編譯方法失仁,按步驟操作一般沒多大問題,如果已經(jīng)安裝過repo工具们何,可以跳過第一步萄焦。

1. 安裝repo

mkdir~/binPATH=~/bin:$PATHcurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+x~/bin/repo

2. 配置git中的姓名和郵箱,已配置可忽略

git config --global user.name"Your Name"git config --global user.email"you@example.com"pet__string">"you@example.com"

3. 創(chuàng)建一個文件夾存放要下載的源碼

mkdir androidx-master-dev

cd androidx-master-dev

4. 使用repo命令下載源碼倉庫

repoinit-u https://android.googlesource.com/platform/manifest-b androidx-master-devrepo sync-j8-c

5. 使用命令以Android Studio打開源碼庫

cd androidx-master-dev/frameworks/support/

./studiow

第一次打開可能會自動下載一個最新的Android Studio冤竹,稍等一會兒拂封,就可以看到熟悉的界面了。

如圖贴见,Lifecycle烘苹、LiveData和ViewModel三大組件的代碼都在lifecycle包下躲株。

組件介紹

為了對分析工作有個感性認(rèn)識片部,先過一下各個組件的作用和簡單用法。

Lifecycle

Lifecycle可以方便我們處理Activity和Fragment的生命周期,可以將一些邏輯更加內(nèi)聚和解耦档悠,比如把資源的釋放操作從Activity的回調(diào)代碼中解耦出來廊鸥,放到資源管理類中自動進(jìn)行。該組件是后兩個組件的基石辖所,理解它的原理也有助于我們理解LiveData是如何保證不會造成內(nèi)存泄漏的惰说。

下面是一個簡單的使用示例,在自定義LifecycleObserver的實現(xiàn)接口上缘回,用注解的方式聲明與生命周期相關(guān)聯(lián)的方法吆视。最后通過lifecycleOwner的getLifecycle()接口拿到Lifecycle管理類,并將定義LifecycleObserver的實現(xiàn)接口注冊進(jìn)去酥宴。LifecycleOwner通常是一個Activity或Fragment的實例啦吧。

MyObserverimplementsLifecycleObserver{@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)publicvoidconnectListener(){...}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)publicvoiddisconnectListener(){...}}lifecycleOwner.getLifecycle().addObserver(newMyObserver());

LiveData

LiveData是一個數(shù)據(jù)持有組件,主要用來通知數(shù)據(jù)觀察者數(shù)據(jù)發(fā)生了更新拙寡,它通過與LifecycleOwner組件綁定授滓,實現(xiàn)可以只在頁面活躍狀態(tài)下發(fā)起通知,并在頁面銷毀時自動取消訂閱肆糕,防止內(nèi)存泄漏般堆。

下面的簡單示例中,直接創(chuàng)建了一個MutableLiveData對象诚啃,他持有String類型的數(shù)據(jù)淮摔,通過它的observe()方法,將LifecycleOwner和監(jiān)聽者傳入始赎,實現(xiàn)感知生命周期并觀察數(shù)據(jù)的功能噩咪。

MutableLiveData<String>liveString=newMutableLiveData<>();liveString.observe(mOwner,newObserver<String>(){@OverridepublicvoidonChanged(@NullablefinalString s){Log.d(TAG,"onChanged() called with: s = ["+s+"]");}});liveString.setValue("LiveData使用案例");

ViewModel

ViewModel是MVVM中的VM,被設(shè)計用來管理View依賴的數(shù)據(jù)极阅,通常是持有LiveData和相關(guān)的處理邏輯胃碾。ViewModel管理的數(shù)據(jù)有一個特點,就是不會隨著頁面配置改變而銷毀筋搏,但在頁面銷毀時則會正常跟著銷毀仆百。

下面的例子中,自定義了一個ViewModel奔脐,管理users這組數(shù)據(jù)俄周,并且封裝了加載users的處理邏輯。而View只需要監(jiān)聽users髓迎,在回調(diào)中根據(jù)users處理界面就好峦朗,這樣就做到了界面和數(shù)據(jù)的分離。

publicclassMyViewModelextendsViewModel{privateMutableLiveData<List<User>>users;publicLiveData<List<User>>getUsers(){if(users==null){users=newMutableLiveData<List<User>>();loadUsers();}returnusers;}privatevoidloadUsers(){// Do an asynchronous operation to fetch users.}}

組件關(guān)系

在實際的MVVM場景中排龄,最常使用的是ViewModel和LiveData的API波势,比較通用的方式是ViewModel持有一個或多個LiveData,也就是需要我們開發(fā)者設(shè)計出這兩個組件的聚合關(guān)系。而Lifecycle組件尺铣,則是在調(diào)用LiveData的addOberver()方法時用到的拴曲,這個方法需要傳入一個LifecycleOwner對象,LifecycleOwner作為一個接口凛忿,是Lifecycle組件的重要組成部分澈灼。

通過分析組件的源碼,可以從設(shè)計角度發(fā)現(xiàn)店溢,Lifecycle組件的能力是LiveData和ViewModel實現(xiàn)的根本叁熔,LiveData的頁面活躍狀態(tài)下才發(fā)起通知、頁面銷毀時自動取消訂閱床牧,以及ViewModel銷毀所管理的數(shù)據(jù)的特性者疤,都是通過直接使用Lifecycle實現(xiàn)的,可以說Lifecycle是LiveData和ViewModel的重要組成部分叠赦。

源碼分析方法

01自底向上

該方法是從使用細(xì)節(jié)出發(fā)驹马,提出問題,再進(jìn)入源碼中探究答案除秀,最后匯總出組件關(guān)系圖糯累,獲得上層視角。在這里以自下向上的方法册踩,分析一下LifeCycle的源碼泳姐。

提出問題

首先,還是看這個使用示例:

MyObserverimplementsLifecycleObserver{@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)publicvoidconnectListener(){...}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)publicvoiddisconnectListener(){...}}lifecycleOwner.getLifecycle().addObserver(newMyObserver());

針對該示例所實現(xiàn)的作用暂吉,可以從輸入胖秒、處理和輸出這三個軟件過程角度提出問題:1、Activity/Fragment的生命周期如何轉(zhuǎn)化為不同類型的Lifecycle.Event慕的?2阎肝、Lifecycle.Event經(jīng)過哪些處理?3肮街、如何分發(fā)到特定的LifecycleObserver實現(xiàn)风题?

探究答案

Activity/Fragment的生命周期如何轉(zhuǎn)化為不同類型的Lifecycle.Event

先來看看第一個問題怎么在源碼中找到答案,不過在這以前嫉父,不妨先簡單猜測一下沛硅,最直接的想法是:直接在生命周期回調(diào)方法中創(chuàng)建對應(yīng)類型的Event。在接下來的分析中绕辖,便可以著重于是不是這么實現(xiàn)的摇肌,如果更復(fù)雜,那么還有哪些是需要被特別考慮到的仪际。

ComponentActiivty相關(guān)代碼

publicclassComponentActivityextendsActivityimplementsLifecycleOwner,Component{privateLifecycleRegistrymLifecycleRegistry=newLifecycleRegistry(this);protectedvoidonCreate(@NullableBundlesavedInstanceState){super.onCreate(savedInstanceState);ReportFragment.injectIfNeededIn(this);}@CallSuperprotectedvoidonSaveInstanceState(BundleoutState){Lifecyclelifecycle=this.getLifecycle();if(lifecycleinstanceofLifecycleRegistry){((LifecycleRegistry)lifecycle).setCurrentState(State.CREATED);}super.onSaveInstanceState(outState);}publicLifecyclegetLifecycle(){returnthis.mLifecycleRegistry;}}

從ComponentActiivty這個類中围小,可以看到它實現(xiàn)了LifecycleOwner接口昵骤,該類的子類也就有了提供Lifecycle的能力,除了LifecycleOwner的getLifecycle接口的實現(xiàn)吩抓,另外比較重要的就是ReportFragment.injectIfNeededIn(this)這條語句,以及它持有了一個Lifecycle的主要實現(xiàn)類LifecycleRegistry的示例赴恨。

ReportFragment的主要實現(xiàn)

publicclassReportFragmentextendsFragment{privatestaticfinalStringREPORT_FRAGMENT_TAG="android.arch.lifecycle"+".LifecycleDispatcher.report_fragment_tag";publicstaticvoidinjectIfNeededIn(Activityactivity){if(Build.VERSION.SDK_INT>=29){// On API 29+, we can register for the correct Lifecycle callbacks directlyactivity.registerActivityLifecycleCallbacks(newLifecycleCallbacks());}// 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 eventsandroid.app.FragmentManagermanager=activity.getFragmentManager();if(manager.findFragmentByTag(REPORT_FRAGMENT_TAG)==null){manager.beginTransaction().add(newReportFragment(),REPORT_FRAGMENT_TAG).commit();// Hopefully, we are the first to make a transaction.manager.executePendingTransactions();}}//...@OverridepublicvoidonStart(){super.onStart();dispatchStart(mProcessListener);dispatch(Lifecycle.Event.ON_START);}privatevoiddispatch(@NonNullLifecycle.Eventevent){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.injectIfNeededIndispatch(getActivity(),event);}}staticvoiddispatch(@NonNullActivityactivity,@NonNullLifecycle.Eventevent){if(activityinstanceofLifecycleRegistryOwner){((LifecycleRegistryOwner)activity).getLifecycle().handleLifecycleEvent(event);return;}if(activityinstanceofLifecycleOwner){Lifecyclelifecycle=((LifecycleOwner)activity).getLifecycle();if(lifecycleinstanceofLifecycleRegistry){((LifecycleRegistry)lifecycle).handleLifecycleEvent(event);}}}//...}

靜態(tài)方法injectIfNeededIn的主要作用就是為Activity提供Lifecycle能力疹娶,這里分成了兩種情況,在Android

10及以上伦连,Activity的源碼修改成自己可以注冊進(jìn)LifecycleCallbacks監(jiān)聽器雨饺。而為了兼容舊版本,則需要Fragment的生命周期回調(diào)中進(jìn)行分發(fā)惑淳,這也就是與最初推測相比特殊的地方额港,可以更加留意。不過這兩種情況都是根據(jù)生命周期創(chuàng)建了Event枚舉型歧焦,并最終都經(jīng)過靜態(tài)方法dispatch移斩,調(diào)用了Lifecyce的handleLifecycleEvent方法。

Lifecycle.Event經(jīng)過哪些處理

LifecycRegistry

publicclassLifecycleRegistryextends Lifecycle{/**

? ? * 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),

? ? */privateFastSafeIterableMap<LifecycleObserver,ObserverWithState>mObserverMap=newFastSafeIterableMap<>();privateStatemState;privatefinal WeakReference<LifecycleOwner>mLifecycleOwner;publicLifecycleRegistry(@NonNullLifecycleOwnerprovider){mLifecycleOwner=newWeakReference<>(provider);mState=INITIALIZED;}publicvoidhandleLifecycleEvent(@NonNullLifecycle.Eventevent){Statenext=getStateAfter(event);moveToState(next);}privatevoidmoveToState(Statenext){if(mState==next){return;}mState=next;......sync();......}...}

跟著源碼可以定位到Lifecycle的實現(xiàn)類LifecycRegistry中绢馍,它主要是封裝了對Lifecycle.Event的操作向瓷,包括了Lifecycle.Event與Lifecycle.State的同步,以及Lifecycle.State變化后通知觀察者舰涌。

先來看handleLifecycleEnvent的實現(xiàn)猖任,通過傳進(jìn)來的event獲取一個state枚舉值,具體的實現(xiàn)代碼如下:

staticStategetStateAfter(Eventevent){switch(event){caseON_CREATE:caseON_STOP:returnState.CREATED;caseON_START:caseON_PAUSE:returnState.STARTED;caseON_RESUME:returnState.RESUMED;caseON_DESTROY:returnState.DESTROYED;caseON_ANY:default:thrownewIllegalArgumentException("Unexpected event value "+event);}}

官網(wǎng)中有一張圖用來解釋Event和State的對應(yīng)關(guān)系

image.png

getStateAfter()方法既是獲取Event事件之后的狀態(tài)瓷耙,可以從圖中的箭頭方向可知具體的狀態(tài)值朱躺,比如ON_START和ON_PAUSE的箭頭都指向了STARTED狀態(tài),也就是這倆個事件后Lifecycle處于STARTED狀態(tài)搁痛。

回到handleLifecycleEvent()方法长搀,獲取新狀態(tài)后,就調(diào)用了moveToState()方法鸡典,該方法主要是判斷新狀態(tài)與當(dāng)前狀態(tài)相比是否發(fā)生改變骏全,如果已改變,則調(diào)用sync()同步方法繼續(xù)處理溺职。

在進(jìn)一步跟蹤方法調(diào)用前涕滋,不妨先看看LifecycleRegistry有哪些屬性,除了上面提到的mState來表示當(dāng)前Lifecycle的狀態(tài)外疗垛,還有一個比較特殊和重要的屬性是mObserverMap症汹。

/**

* 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<LifecycleObserver,ObserverWithState>mObserverMap=newFastSafeIterableMap<>();

該屬性可看作是一個自定義的Map,是一個可遍歷的集合贷腕,也就是說其中的元素是有序的背镇,封裝了監(jiān)聽者LifecycleObserver和監(jiān)聽者的封裝ObserverWithState之間的映射關(guān)系咬展,根據(jù)注釋可以知道,在遍歷操作其中的監(jiān)聽者時瞒斩,會保證其中監(jiān)聽者的狀態(tài)是從大到小排序的破婆。

監(jiān)聽者的封裝ObserverWithState則是維護(hù)了每一個監(jiān)聽者和其狀態(tài),該狀態(tài)主要是為了給調(diào)用事件分發(fā)前的判斷胸囱,另外祷舀,在分發(fā)Event事件后會同步更新自己的狀態(tài)。

staticclassObserverWithState{StatemState;LifecycleEventObservermLifecycleObserver;ObserverWithState(LifecycleObserverobserver,StateinitialState){mLifecycleObserver=Lifecycling.lifecycleEventObserver(observer);mState=initialState;}voiddispatchEvent(LifecycleOwnerowner,Eventevent){StatenewState=getStateAfter(event);mState=min(mState,newState);mLifecycleObserver.onStateChanged(owner,event);mState=newState;}}

接下來繼續(xù)跟蹤方法調(diào)用烹笔,來看看sync()做了哪些處理裳扯。

privatevoidsync(){LifecycleOwnerlifecycleOwner=mLifecycleOwner.get();if(lifecycleOwner==null){thrownewIllegalStateException("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);}Entry<LifecycleObserver,ObserverWithState>newest=mObserverMap.newest();if(!mNewEventOccurred&&newest!=null&&mState.compareTo(newest.getValue().mState)>0){forwardPass(lifecycleOwner);}}mNewEventOccurred=false;}

該方法通過比較當(dāng)前狀態(tài)和mObserverMap元素的枚舉值來確定是否分發(fā)事件,由于mObserverMap里元素是按狀態(tài)的大到小排序的谤职,所以這里只需要拿第一位和最后一位元素的狀態(tài)與當(dāng)前狀態(tài)比較饰豺,就可以判斷是否需要分發(fā)事件,以及是分發(fā)降級事件允蜈,還是分發(fā)升級事件冤吨。再具體一點說,如果mObserverMap里最大狀態(tài)比當(dāng)前狀態(tài)大饶套,那就需要調(diào)用backwardPass()锅很,遍歷mObserverMap,同步其中每一個observer狀態(tài)的同時凤跑,分發(fā)降級事件爆安,反之,如果mObserverMap里最小狀態(tài)比當(dāng)前狀態(tài)小仔引,就調(diào)用forwardPass()分發(fā)升級事件扔仓。

privatevoidbackwardPass(LifecycleOwnerlifecycleOwner){Iterator<Entry<LifecycleObserver,ObserverWithState>>descendingIterator=mObserverMap.descendingIterator();while(descendingIterator.hasNext()&&!mNewEventOccurred){Entry<LifecycleObserver,ObserverWithState>entry=descendingIterator.next();ObserverWithStateobserver=entry.getValue();while((observer.mState.compareTo(mState)>0&&!mNewEventOccurred&&mObserverMap.contains(entry.getKey()))){Eventevent=downEvent(observer.mState);pushParentState(getStateAfter(event));observer.dispatchEvent(lifecycleOwner,event);popParentState();}}}privatevoidforwardPass(LifecycleOwnerlifecycleOwner){Iterator<Entry<LifecycleObserver,ObserverWithState>>ascendingIterator=mObserverMap.iteratorWithAdditions();while(ascendingIterator.hasNext()&&!mNewEventOccurred){Entry<LifecycleObserver,ObserverWithState>entry=ascendingIterator.next();ObserverWithStateobserver=entry.getValue();while((observer.mState.compareTo(mState)<0&&!mNewEventOccurred&&mObserverMap.contains(entry.getKey()))){pushParentState(observer.mState);observer.dispatchEvent(lifecycleOwner,upEvent(observer.mState));popParentState();}}}

backwardPass()和forwardPass()類似,分別是以降序和升序的方式遍歷mObserverMap中的observer咖耘,再以內(nèi)部循環(huán)通過downEvent()和upEvent()獲取下一步的Event事件翘簇,并通過observer.dispatchEvent()分發(fā)事件和同步狀態(tài)。直到mObserverMap中的每一個observer的狀態(tài)都與當(dāng)前狀態(tài)一致為止儿倒。

privatestaticEventdownEvent(State state){switch(state){caseINITIALIZED:thrownewIllegalArgumentException();caseCREATED:returnON_DESTROY;caseSTARTED:returnON_STOP;caseRESUMED:returnON_PAUSE;caseDESTROYED:thrownewIllegalArgumentException();}thrownewIllegalArgumentException("Unexpected state value "+state);}privatestaticEventupEvent(State state){switch(state){caseINITIALIZED:caseDESTROYED:returnON_CREATE;caseCREATED:returnON_START;caseSTARTED:returnON_RESUME;caseRESUMED:thrownewIllegalArgumentException();}thrownewIllegalArgumentException("Unexpected state value "+state);}

downEvent()和upEvent()的實現(xiàn)同樣可以從官網(wǎng)給的Event與State的關(guān)系圖中找到對應(yīng)關(guān)系版保。下面再放一下這張圖。

downEvent()降級事件就是狀態(tài)向后箭頭對應(yīng)的事件夫否,而upEvent()升級事件則是狀態(tài)向前箭頭對應(yīng)的事件彻犁。比如說CREATED的升級事件是ON_START,通過ON_START凰慈,CREATED升級為STARTED汞幢。CREATED的降級事件是ON_DESTROY,通過ON_DESTROY微谓,CREATED降級為DESTROY森篷。

方法調(diào)用流轉(zhuǎn)到這里输钩,已經(jīng)分析完Event從創(chuàng)建到分發(fā)的處理過程,接下來就來解決剛開始提出的第三個問題仲智。

如何分發(fā)到特定的LifecycleObserver實現(xiàn)

通過ObserverWithState买乃,可以發(fā)現(xiàn)dispatchEvent()方法是直接調(diào)用mLifecycleObserver接口的onStateChanged()進(jìn)行的事件分發(fā),那么mLifecycleObserver的具體實現(xiàn)是怎樣的呢钓辆?通過

mLifecycleObserver =

Lifecycling.lifecycleEventObserver(observer)可以知道靜態(tài)方法Lifecycling.lifecycleEventObserver()對傳入的監(jiān)聽者進(jìn)行了處理剪验,接下來就來看看該方法是怎么實現(xiàn)的。

staticLifecycleEventObserverlifecycleEventObserver(Objectobject){boolean isLifecycleEventObserver=objectinstanceof LifecycleEventObserver;boolean isFullLifecycleObserver=objectinstanceof FullLifecycleObserver;if(isLifecycleEventObserver&&isFullLifecycleObserver){returnnewFullLifecycleObserverAdapter((FullLifecycleObserver)object,(LifecycleEventObserver)object);}if(isFullLifecycleObserver){returnnewFullLifecycleObserverAdapter((FullLifecycleObserver)object,null);}if(isLifecycleEventObserver){return(LifecycleEventObserver)object;}final Class<?>klass=object.getClass();inttype=getObserverConstructorType(klass);if(type==GENERATED_CALLBACK){List<Constructor<?extends GeneratedAdapter>>constructors=sClassToAdapters.get(klass);if(constructors.size()==1){GeneratedAdaptergeneratedAdapter=createGeneratedAdapter(constructors.get(0),object);returnnewSingleGeneratedAdapterObserver(generatedAdapter);}GeneratedAdapter[]adapters=newGeneratedAdapter[constructors.size()];for(inti=0;i<constructors.size();i++){adapters[i]=createGeneratedAdapter(constructors.get(i),object);}returnnewCompositeGeneratedAdaptersObserver(adapters);}returnnewReflectiveGenericLifecycleObserver(object);}

該方法主要將傳入的監(jiān)聽者進(jìn)行封裝岩馍,方便生命周期事件的轉(zhuǎn)發(fā)碉咆,這個封裝分成了三種方式抖韩,每一種可看作是后面的優(yōu)化蛀恩,第一種性能最高,傳入的監(jiān)聽者直接是接口的實例茂浮,但由于生命周期回調(diào)方法比較多双谆,接口的實例默認(rèn)是實現(xiàn)了所有方法,而大部分情況并不需要監(jiān)聽所有生命周期席揽,所以這一部分在java8接口默認(rèn)方法的支持下比較好用顽馋。第二種是判斷傳入的監(jiān)聽者是不是已用注解解析器處理,生成了對應(yīng)的封裝類幌羞,如果項目中配置了注解解析寸谜,那么在編譯過程中就會生成相應(yīng)的類型,相對應(yīng)于運行時反射解析方法的方式属桦,編譯時通過注解生成類型在代碼執(zhí)行時性能更高熊痴。第三種就是運行時反射解析的處理了,限于篇幅聂宾,這里就只追蹤一下第三種方式的處理過程果善。

直接定位到ReflectiveGenericLifecycleObserver類。

classReflectiveGenericLifecycleObserverimplementsLifecycleEventObserver{privatefinalObject mWrapped;privatefinalCallbackInfo mInfo;ReflectiveGenericLifecycleObserver(Object wrapped){mWrapped=wrapped;mInfo=ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());}@OverridepublicvoidonStateChanged(@NonNullLifecycleOwner source,@NonNullEvent event){mInfo.invokeCallbacks(source,event,mWrapped);}}

該類的實現(xiàn)很簡單系谐,在創(chuàng)建實例時巾陕,使用getInfo()方法,通過傳入監(jiān)聽者的class纪他,構(gòu)造出CallbackInfo實例鄙煤。在接受到生命周期回調(diào)后,方法流轉(zhuǎn)到CallbackInfo實例的invokeCallbacks()方法上茶袒。

CallbackInfogetInfo(Class<?>klass){CallbackInfo existing=mCallbackMap.get(klass);if(existing!=null){returnexisting;}existing=createInfo(klass,null);returnexisting;}

getInfo()查看是否已有緩存馆类,如果沒有,就調(diào)用createInfo()方法解析class對象弹谁。

privateCallbackInfocreateInfo(Class<?>klass,@NullableMethod[]declaredMethods){Map<MethodReference,Lifecycle.Event>handlerToEvent=newHashMap<>();...Method[]methods=declaredMethods!=null?declaredMethods:getDeclaredMethods(klass);for(Methodmethod:methods){OnLifecycleEventannotation=method.getAnnotation(OnLifecycleEvent.class);if(annotation==null){continue;}hasLifecycleMethods=true;Class<?>[]params=method.getParameterTypes();intcallType=CALL_TYPE_NO_ARG;if(params.length>0){callType=CALL_TYPE_PROVIDER;if(!params[0].isAssignableFrom(LifecycleOwner.class)){thrownewIllegalArgumentException("invalid parameter type. Must be one and instanceof LifecycleOwner");}}Lifecycle.Eventevent=annotation.value();if(params.length>1){callType=CALL_TYPE_PROVIDER_WITH_EVENT;if(!params[1].isAssignableFrom(Lifecycle.Event.class)){thrownewIllegalArgumentException("invalid parameter type. second arg must be an event");}if(event!=Lifecycle.Event.ON_ANY){thrownewIllegalArgumentException("Second arg is supported only for ON_ANY value");}}if(params.length>2){thrownewIllegalArgumentException("cannot have more than 2 params");}MethodReferencemethodReference=newMethodReference(callType,method);verifyAndPutHandler(handlerToEvent,methodReference,event,klass);}CallbackInfoinfo=newCallbackInfo(handlerToEvent);mCallbackMap.put(klass,info);mHasLifecycleMethods.put(klass,hasLifecycleMethods);returninfo;}

createInfo()方法主要是對類中的方法的遍歷處理乾巧,這里只接受三種類型的方法句喜,使用callType區(qū)分,第一種CALL_TYPE_NO_ARG是沒有參數(shù)的方法沟于,第二種CALL_TYPE_PROVIDER是一個參數(shù)的方法咳胃,參數(shù)類型為LifecycleOwner本身,第三種CALL_TYPE_PROVIDER_WITH_EVENT是二個參數(shù)的方法旷太,第一個參數(shù)類型同CALL_TYPE_PROVIDER一樣展懈,第二個參數(shù)則是ON_ANY枚舉值的Event。

每次遍歷會將方法用MethodReference封裝起來供璧,并使用hanlderToEvent建立MethodReference與event的映射關(guān)系存崖,注意這時候一個方法只能有一種Event事件類型相對應(yīng),最后以hanlderToEvent這個map創(chuàng)建CallbackInfo對象睡毒。

staticclassCallbackInfo{final Map<Lifecycle.Event,List<MethodReference>>mEventToHandlers;final Map<MethodReference,Lifecycle.Event>mHandlerToEvent;CallbackInfo(Map<MethodReference,Lifecycle.Event>handlerToEvent){mHandlerToEvent=handlerToEvent;mEventToHandlers=newHashMap<>();for(Map.Entry<MethodReference,Lifecycle.Event>entry:handlerToEvent.entrySet()){Lifecycle.Eventevent=entry.getValue();List<MethodReference>methodReferences=mEventToHandlers.get(event);if(methodReferences==null){methodReferences=newArrayList<>();mEventToHandlers.put(event,methodReferences);}methodReferences.add(entry.getKey());}}@SuppressWarnings("ConstantConditions")voidinvokeCallbacks(LifecycleOwnersource,Lifecycle.Eventevent,Objecttarget){invokeMethodsForEvent(mEventToHandlers.get(event),source,event,target);invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY),source,event,target);}privatestaticvoidinvokeMethodsForEvent(List<MethodReference>handlers,LifecycleOwnersource,Lifecycle.Eventevent,ObjectmWrapped){if(handlers!=null){for(inti=handlers.size()-1;i>=0;i--){handlers.get(i).invokeCallback(source,event,mWrapped);}}}}

CallbakcInfo在創(chuàng)建時来惧,會解析hanlderToEvent,把一個MethodReference對應(yīng)一個event的關(guān)系演顾,轉(zhuǎn)化為一個event對應(yīng)多個MethodReference供搀,并存入到mEventToHandlers中。這樣在被調(diào)用invokeCallbacks()方法時钠至,只需要從mEventToHandlers中取出對應(yīng)的MethodReference葛虐,就可以回調(diào)監(jiān)聽者了。

staticfinalclassMethodReference{finalint mCallType;finalMethod mMethod;MethodReference(int callType,Method method){mCallType=callType;mMethod=method;mMethod.setAccessible(true);}voidinvokeCallback(LifecycleOwner source,Lifecycle.Event event,Object target){//noinspection TryWithIdenticalCatchestry{switch(mCallType){caseCALL_TYPE_NO_ARG:mMethod.invoke(target);break;caseCALL_TYPE_PROVIDER:mMethod.invoke(target,source);break;caseCALL_TYPE_PROVIDER_WITH_EVENT:mMethod.invoke(target,source,event);break;}}catch(InvocationTargetExceptione){thrownewRuntimeException("Failed to call observer method",e.getCause());}catch(IllegalAccessExceptione){thrownewRuntimeException(e);}}...}

invokeCallback()就是根據(jù)callType對mMethod進(jìn)行反射調(diào)用棉钧,最終執(zhí)行到Lifecycling.lifecycleEventObserver()傳入的監(jiān)聽器的方法實現(xiàn)中屿脐。

到此,Lifecycle的基本流程已經(jīng)分析完了宪卿。接下來的诵,可以使用類圖對Lifecycle的處理流程做下總結(jié)。

類關(guān)系圖

該圖使用simpleUML工具生成

用最初的使用代碼來解釋一下這個類圖愧捕。

lifecycleOwner.getLifecycle().addObserver(newMyObserver());

首先奢驯,通過LifecycleOwner拿到Lifecycle示例,LifecycleOwner是提供獲取Lifecycle實例的接口次绘,一般ComponentActvitiy和Fragment會實現(xiàn)這個接口瘪阁,這個新舊代碼有些差別,使用時需要區(qū)分邮偎。

然后管跺,Lifecycle實例一般具體類型是LifecycleRegistry,它里面使用State管理當(dāng)前的生命周期狀態(tài)禾进,同時每個監(jiān)聽者LifecycleObserver也都有一個State豁跑,表示監(jiān)聽者當(dāng)前的狀態(tài),生命周期事件Event發(fā)生后泻云,會在LifecycleRegistry內(nèi)與State發(fā)生互相轉(zhuǎn)化艇拍,再使用這個轉(zhuǎn)化后最新的State狐蜕,與所有監(jiān)聽者的State比較,到達(dá)完整無誤地通知監(jiān)聽者生命周期事件的目的卸夕。

最后层释,監(jiān)聽者注冊進(jìn)Lifecycle時,一般情況下會使用ReflectiveGenericLifecycleObserver封裝快集,ReflectiveGenericLifecycleObserver本身也是LifecycleObserver接口的實現(xiàn)贡羔,它還封裝了從傳入監(jiān)聽者類中解析的CallbackInfo,在被通知生命周期事件時个初,會使用CallbackInfo反射調(diào)用到用戶聲明的接口方法實現(xiàn)上乖寒。

自底向上方法總結(jié)

自底向上的方式分析源碼主要在于分析前問題的提出,上面應(yīng)用了軟件過程中的輸入院溺、處理和輸出這三個角度提出問題楣嘁,算是比較通用的一種方式。問題提出后覆获,便可以以解決問題為目的分析源碼马澈,不至于在茫茫源碼中迷失了方向瓢省。解決完問題弄息,緊接著把源碼的主要流程梳理一遍,做出總結(jié)勤婚,即可以加深對原理的理解摹量。

02自頂向下

自頂向下分析源碼與自底向上在思路上正好相反,需要先繪制出組件的類關(guān)系圖馒胆,然后抽出主要方法缨称,進(jìn)一步解析方法,從而掌握實現(xiàn)細(xì)節(jié)祝迂,它適合于在對源碼組件有一個整體上的了解前提下進(jìn)行睦尽,可以深刻掌握組件的原理特性。接下來就使用該方法總結(jié)出LiveData的特性型雳。

首先還是以一個示例開始:

MutableLiveData<String>liveString=newMutableLiveData<>();liveString.observe(mOwner,newObserver<String>(){@OverridepublicvoidonChanged(@NullablefinalString s){Log.d(TAG,"onChanged() called with: s = ["+s+"]");}});liveString.setValue("LiveData使用案例");

該例子包含了使用LIveData的基本三部分:定義当凡、注冊監(jiān)聽者、更新數(shù)據(jù)纠俭⊙亓浚可以同樣以軟件過程的輸入、處理和輸出三個角度為切入點進(jìn)行分析冤荆。處了定義外朴则,監(jiān)聽者相關(guān)的操作可以看作是輸出,比如注冊钓简、回調(diào)乌妒、注銷汹想。更新數(shù)據(jù)則可以看作是輸入,而處理則是在LiveData的內(nèi)部完成撤蚊。

類關(guān)系圖

LiveData的類關(guān)系圖并不復(fù)雜欧宜,它只有5個類,除了示例中已經(jīng)出現(xiàn)的有Observer和MutableLiveData拴魄,而主要類LiveData則包含和處理的主要邏輯冗茸,LiveData的內(nèi)部類ObserverWrapper和LifecycleBoundObserver則提供了封裝Observer和Lifecycle生命周期管理的能力。這里也可以看出LiveData依賴Livecycle的關(guān)系匹中。

可以從類圖中抽出需要分析的方法夏漱,回到輸入、處理和輸出的角度顶捷,對應(yīng)的就是數(shù)據(jù)更新挂绰、數(shù)據(jù)流轉(zhuǎn)和監(jiān)聽者處理三類方法。

輸入-數(shù)據(jù)更新:postValue()服赎、setValue()葵蒂、onStateChanged()

處理-數(shù)據(jù)流轉(zhuǎn):activeStateChanged()、dispatchingValue()重虑、considerNotify()

輸出-監(jiān)聽者處理:observe()践付、removeObserver()、onChanged()

接下來缺厉,可以使用在源碼方法間快速跳轉(zhuǎn)的方式永高,手動定位并列出相應(yīng)處理鏈。

從該圖中可以看出觸發(fā)數(shù)據(jù)通知的兩個處理鏈:

1. 注冊監(jiān)聽者后提针,可以接收到Lifecycle事件命爬,這時候可能會移除監(jiān)聽者,也可能觸發(fā)了數(shù)據(jù)通知

2. 手動postValue或setValue觸發(fā)數(shù)據(jù)通知

接下來辐脖,便以這兩個任務(wù)鏈的順序饲宛,對每個方法進(jìn)行分析。

observer()注冊監(jiān)聽者

@MainThreadpublicvoidobserve(@NonNull LifecycleOwner owner,@NonNull Observer<?superT>observer){assertMainThread("observe");if(owner.getLifecycle().getCurrentState()==DESTROYED){// ignorereturn;}LifecycleBoundObserver wrapper=newLifecycleBoundObserver(owner,observer);ObserverWrapper existing=mObservers.putIfAbsent(observer,wrapper);if(existing!=null&&!existing.isAttachedTo(owner)){thrownewIllegalArgumentException("Cannot add the same observer"+" with different lifecycles");}if(existing!=null){return;}owner.getLifecycle().addObserver(wrapper);}

該方法就是把Lifecycle持有對象LifecycleOwner和一個監(jiān)聽者observer傳進(jìn)來嗜价,實現(xiàn)這個監(jiān)聽者在這個生命周期作用域下對LiveData的數(shù)據(jù)進(jìn)行監(jiān)聽艇抠。這里主要的處理是對observer使用Lifecycle的監(jiān)聽者LifecycleBoundObserver進(jìn)行了封裝,并存入管理所有監(jiān)聽者的mObservers中炭剪。這里除了過濾避免重復(fù)外练链,還對監(jiān)聽者對應(yīng)的LifecycleOwner進(jìn)行了判斷,防止一個監(jiān)聽者處于多個Lifecycle作用域進(jìn)而導(dǎo)致混亂的情況發(fā)生奴拦。

LifecycleBoundObserver的onStateChanged()

classLifecycleBoundObserverextendsObserverWrapperimplementsLifecycleEventObserver{@NonNullfinalLifecycleOwnermOwner;LifecycleBoundObserver(@NonNullLifecycleOwnerowner,Observer<?superT>observer){super(observer);mOwner=owner;}@OverridebooleanshouldBeActive(){returnmOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@OverridepublicvoidonStateChanged(@NonNullLifecycleOwnersource,@NonNullLifecycle.Eventevent){if(mOwner.getLifecycle().getCurrentState()==DESTROYED){removeObserver(mObserver);return;}activeStateChanged(shouldBeActive());}@OverridebooleanisAttachedTo(LifecycleOwnerowner){returnmOwner==owner;}@OverridevoiddetachObserver(){mOwner.getLifecycle().removeObserver(this);}}

onStateChanged()的邏輯是LifecycleBoundObserver中對接口LifecycleEventObserver的實現(xiàn)媒鼓,通過對Lifecycle組件的了解,可以知道在LifecycleOwner的生命周期發(fā)生改變時,onStateChanged()方法就會被調(diào)用到绿鸣。這里判斷如果LifecycleOwner銷毀了疚沐,那么就移除這個監(jiān)聽者,達(dá)到防止內(nèi)存泄漏的目的潮模,其它情況則會以shouldBeActivie()為值調(diào)用activeStateChanged()方法亮蛔。shouldBeActivie()判斷LifecycleOwner的狀態(tài)是否處于STARTED之后,也就是是否顯示在屏幕中擎厢,這里表明了LiveData的另一個特性究流,默認(rèn)情況下,顯示在屏幕中的頁面中的監(jiān)聽者才會收到數(shù)據(jù)更新的通知动遭。

ObserverWrapper的activeStateChanged()

privateabstractclassObserverWrapper{finalObserver<?superT>mObserver;booleanmActive;intmLastVersion=START_VERSION;ObserverWrapper(Observer<?superT>observer){mObserver=observer;}abstractbooleanshouldBeActive();booleanisAttachedTo(LifecycleOwnerowner){returnfalse;}voiddetachObserver(){}voidactiveStateChanged(booleannewActive){if(newActive==mActive){return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive=newActive;booleanwasInactive=LiveData.this.mActiveCount==0;LiveData.this.mActiveCount+=mActive?1:-1;if(wasInactive&&mActive){onActive();}if(LiveData.this.mActiveCount==0&&!mActive){onInactive();}if(mActive){dispatchingValue(this);}}}

activeStateChanged()方法是在LifecycleBoundObserver的父類ObserverWrapper中實現(xiàn)的芬探,先看ObserverWrapper的屬性,ObserverWrapper不僅封裝了監(jiān)聽者厘惦,還用mActive管理是否為活躍狀態(tài)偷仿,以及用mLastVersion管理監(jiān)聽者當(dāng)前的數(shù)據(jù)版本∠叮回到activeStateChanged()方法酝静,這里的處理主要分三點,首先羡玛,用活躍狀態(tài)是否發(fā)生變化做了一個閉路邏輯别智,防止重復(fù)處理,比如onStart()處理后又接收到onResume()缝左。其次亿遂,更新當(dāng)前狀態(tài)浓若,并判斷如果這是第一個監(jiān)聽者活躍渺杉,就調(diào)用onActive()方法,如果是最后一個監(jiān)聽者非活躍挪钓,就調(diào)用onInactive()方法是越。最后,如果是新的活躍狀態(tài)碌上,則以當(dāng)前ObserverWrapper對象為參數(shù)值調(diào)用dispatchingValue()方法分發(fā)事件倚评。

setValue()

@MainThreadprotectedvoidsetValue(Tvalue){assertMainThread("setValue");mVersion++;mData=value;dispatchingValue(null);}

setValue()是LiveData的一個成員方法,用于在主線程中手動更新LiveData中的值馏予,這里先將數(shù)據(jù)版本mVersion自增后天梧,更新mData的值,并以null為參數(shù)值調(diào)用dispatchingValue()方法霞丧。

postValue()

protectedvoidpostValue(Tvalue){booleanpostTask;synchronized(mDataLock){postTask=mPendingData==NOT_SET;mPendingData=value;}if(!postTask){return;}ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}privatefinalRunnablemPostValueRunnable=newRunnable(){@SuppressWarnings("unchecked")@Overridepublicvoidrun(){ObjectnewValue;synchronized(mDataLock){newValue=mPendingData;mPendingData=NOT_SET;}setValue((T)newValue);}};

postValue()也是用來手動更新LiveData中的值的呢岗,不過和setValue()有區(qū)別的是,它可以在非主線程中調(diào)用。它的處理就是在保證線程安全的前提下后豫,通知主線程調(diào)用setValue()方法更新數(shù)據(jù)悉尾。

具體細(xì)節(jié)是,定義一個volatile修飾的成員變量mPandingData挫酿,用作線程間共享數(shù)據(jù)构眯,這個變量的默認(rèn)值為NOT_SET。通過對共享數(shù)據(jù)mPandingData的讀寫訪問進(jìn)行加鎖的方式實現(xiàn)線程安全早龟,同時惫霸,主線程讀取mPandingData的值后,也就被認(rèn)為是消費掉了共享數(shù)據(jù)葱弟,這時會把mPandingData設(shè)置會默認(rèn)值NOT_SET它褪,而其他線程在拿到鎖后寫入mPandingData,也就是生產(chǎn)共享數(shù)據(jù)時翘悉,只有之前主線程已消費掉或還未生產(chǎn)過共享數(shù)據(jù)茫打,才會向主線程發(fā)送處理消息。

這個邏輯實現(xiàn)了另外一個特性妖混,當(dāng)主線程還沒來得及處理消息老赤,這時多個線程同時排隊拿鎖更新數(shù)據(jù),主線程最終只會使用最后最新的數(shù)據(jù)去處理制市,調(diào)用setValue()通知監(jiān)聽者抬旺。

dispatchingValue()

無論是生命周期回調(diào)的activeStateChanged()還是手動發(fā)起數(shù)據(jù)更新setValue(),最終都通過dispatchingValue()完成了數(shù)據(jù)更新的分發(fā)祥楣。

voiddispatchingValue(@NullableObserverWrapper initiator){if(mDispatchingValue){mDispatchInvalidated=true;return;}mDispatchingValue=true;do{mDispatchInvalidated=false;if(initiator!=null){considerNotify(initiator);initiator=null;}else{for(Iterator<Map.Entry<Observer<?superT>,ObserverWrapper>>iterator=mObservers.iteratorWithAdditions();iterator.hasNext();){considerNotify(iterator.next().getValue());if(mDispatchInvalidated){break;}}}}while(mDispatchInvalidated);mDispatchingValue=false;}

dispatchingValue()如果傳入的參數(shù)不為null开财,那么就針對該對象單獨分發(fā),對應(yīng)的就是生命周期回調(diào)的調(diào)用误褪。而如果傳入了null责鳍,那就遍歷mObservers,對每一個監(jiān)聽者完成分發(fā)兽间。每次分發(fā)是調(diào)用considerNotify()完成历葛。

dispatchingValue()的處理中首先使用了兩個成員變量mDispatchingValue和mDispatchInvalidated做了一個短路邏輯,這倆成員變量分別表示是否處于分發(fā)中和分發(fā)的數(shù)據(jù)是否過期嘀略。進(jìn)入分發(fā)過程時恤溶,會將mDispatchingValue置為true,mDispatchInvalidated置為false帜羊,這時表示處于正常的分發(fā)狀態(tài)咒程。如果在正常分發(fā)狀態(tài)時,再有新的分發(fā)請求讼育,那么就會將mDispatchInvalidated值為true帐姻,正常的分發(fā)狀態(tài)便會中斷粮宛,重新開始分發(fā)。這就實現(xiàn)了一個特性卖宠,只對監(jiān)聽者通知最新的數(shù)據(jù)巍杈。

可以使用下面的單元測試加深對該特性的理解。

@TestpublicvoidtestSetValueDuringSetValue(){mOwner.handleLifecycleEvent(ON_START);finalObserverobserver1=spy(newObserver<String>(){@OverridepublicvoidonChanged(Stringo){assertThat(mInObserver,is(false));mInObserver=true;if(o.equals(("bla"))){mLiveData.setValue("gt");}mInObserver=false;}});finalObserverobserver2=spy(newFailReentranceObserver());mLiveData.observe(mOwner,observer1);mLiveData.observe(mOwner,observer2);mLiveData.setValue("bla");verify(observer1,Mockito.atMost(2)).onChanged("gt");verify(observer2,Mockito.atMost(2)).onChanged("gt");}

這個單元測試在源碼庫中可以找到扛伍,有興趣的同學(xué)可以debug一下看看處理流程筷畦,后面會介紹一下這個技巧,這里先簡單描述一下代碼執(zhí)行過程刺洒。

在這個單元測試中鳖宾,對于mLiveData有兩個監(jiān)聽者observer1和observer2,正常情況下逆航,當(dāng)mLiveData.setValue("bla")時鼎文,dispatchingValue()對監(jiān)聽者進(jìn)行遍歷,兩個監(jiān)聽者應(yīng)該依次收到數(shù)據(jù)“bla”的通知因俐,但是observer1在收到“bla”后拇惋,又執(zhí)行mLiveData.setValue("gt")發(fā)起了新的數(shù)據(jù)更新,這個第二次dispatchingValue()便會短路抹剩,且會中斷并重啟第一次的遍歷撑帖,于是observer1會再次收到“gt”,然后才是observer2澳眷,它只會收到“gt”胡嘿。

這個流程便是保證了數(shù)據(jù)更新只通知最新的,在實際開發(fā)中如果遇到setValue()的過程中再次setValue()的情況钳踊,就需要特別注意一下這條特性衷敌。

considerNotify()

privatevoidconsiderNotify(ObserverWrapper observer){if(!observer.mActive){return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if(!observer.shouldBeActive()){observer.activeStateChanged(false);return;}if(observer.mLastVersion>=mVersion){return;}observer.mLastVersion=mVersion;observer.mObserver.onChanged((T)mData);}

considerNotify()才是最終發(fā)起數(shù)據(jù)更新通知的方法,這里首先檢查了監(jiān)聽者及其所處生命周期的活躍狀態(tài)拓瞪,并比較了監(jiān)聽者的數(shù)據(jù)版本和當(dāng)前數(shù)據(jù)版本缴罗,保證了監(jiān)聽者所在頁面處于前臺時并且數(shù)據(jù)版本需要更新時才發(fā)起通知。發(fā)起通知前會更新監(jiān)聽者的數(shù)據(jù)版本到最新吴藻,確保數(shù)據(jù)一致瞒爬。

LiveData特性

分析完這些主要方法后,便可以對LiveData的特性做一個總結(jié)了沟堡,以便在實際使用過程中更加得心應(yīng)手。

1. 一個監(jiān)聽者只能處于一個生命周期作用域中

2. 監(jiān)聽者通過Lifecycle的特性實現(xiàn)頁面銷毀后自動注銷矢空,防止內(nèi)存泄漏

3. 監(jiān)聽者只會在所處的頁面在前臺的情況下收到數(shù)據(jù)更新的通知

4. 由于Lifecycle的特性航罗,監(jiān)聽者如果在所處頁面在前臺的情況下,注冊進(jìn)LiveData屁药,會立即調(diào)用到considerNotify()粥血,這時候如果LiveData的數(shù)據(jù)版本變化過,便會立即對該監(jiān)聽者發(fā)送通知,這也就是所謂的粘性事件复亏。

5. postValue()經(jīng)過線程安全處理趾娃,最終通過setValue()發(fā)起數(shù)據(jù)更新通知。N次postValue()并不能保證同樣N次setValue()缔御,post中防止了重復(fù)向主線程發(fā)消息抬闷,主線程中只會拿當(dāng)前最新的值調(diào)用setValue()。

6. N次setValue()同樣不能保證活躍的監(jiān)聽者被通知到N次耕突,LiveData保證了只通知最新的數(shù)據(jù)笤成。

自頂向下分析總結(jié)

自頂向下方法主要難點在于從類關(guān)系圖中找出要分析的核心方法及其調(diào)用關(guān)系鏈,這需要提前對該組件有一定的理解眷茁,本次LiveData的分析先使用了軟件過程的三個角度框定了方法范圍炕泳,再通過在源碼快速跳轉(zhuǎn)的方式整理出調(diào)用鏈,大家可以在自己分析時參考上祈。確定了要分析的方法后培遵,接下來就是細(xì)心的分析工作,需要注意的是在這個過程中要總結(jié)出其實現(xiàn)的特性登刺,從而更好地指導(dǎo)在日常實際開發(fā)工作荤懂。

03逐類分析

逐類分析的方式適合對一個組件不了解的情況下使用,以期快速地掌握大概原理塘砸。整個過程就是以總結(jié)類功能為目的节仿,對組件的相關(guān)類逐個通過跳轉(zhuǎn)方法進(jìn)入,快速閱讀并做出總結(jié)掉蔬,掌握類功能定義廊宪,為以后使用其它方式進(jìn)一步理解源碼做好準(zhǔn)備。下面以這個方式分析一下ViewModel的源碼女轿。

首先箭启,還是先看一個例子:

publicclassMyViewModelextendsViewModel{privateMutableLiveData<List<User>>users;publicLiveData<List<User>>getUsers(){if(users==null){users=newMutableLiveData<List<User>>();loadUsers();}returnusers;}privatevoidloadUsers(){// Do an asynchronous operation to fetch users.}}publicclassMyActivityextendsAppCompatActivity{publicvoidonCreate(BundlesavedInstanceState){MyViewModelmodel=newViewModelProvider(this).get(MyViewModel.class);}}

該例子定義了一個ViewModel的子類MyViewModel,然后通過ViewModelProvider的實例方法get()獲取到MyViewModel的實例蛉迹。

ViewModelProvider

/**

* Creates {@code ViewModelProvider}. This will create {@code ViewModels}

* and retain them in a store of the given {@code ViewModelStoreOwner}.

* <p>

* This method will use the

* {@link HasDefaultViewModelProviderFactory#getDefaultViewModelProviderFactory() default factory}

* if the owner implements {@link HasDefaultViewModelProviderFactory}. Otherwise, a

* {@link NewInstanceFactory} will be used.

*/publicViewModelProvider(@NonNullViewModelStoreOwner owner){this(owner.getViewModelStore(),owner instanceof HasDefaultViewModelProviderFactory?((HasDefaultViewModelProviderFactory)owner).getDefaultViewModelProviderFactory():NewInstanceFactory.getInstance());}/**

* Creates {@code ViewModelProvider}, which will create {@code ViewModels} via the given

* {@code Factory} and retain them in the given {@code store}.

*

* @param store? {@code ViewModelStore} where ViewModels will be stored.

* @param factory factory a {@code Factory} which will be used to instantiate

*? ? ? ? ? ? ? ? new {@code ViewModels}

*/publicViewModelProvider(@NonNullViewModelStore store,@NonNullFactory factory){mFactory=factory;mViewModelStore=store;}

從構(gòu)造方法中可以看出ViewModelProvider需要ViewModelStore和Factory兩個類型的成員變量才能構(gòu)造處理傅寡,分別是mViewModelStore和mFactory,ComponentActivity和Fragment分別都實現(xiàn)了ViewModelStoreOwner和HasDefaultViewModelProviderFactory接口北救,所以都可以從中獲取到ViewModelStore和Factory的實例荐操。

@NonNull@MainThreadpublic<TextendsViewModel> T get(@NonNull Class<T> modelClass) {String canonicalName=modelClass.getCanonicalName();if(canonicalName==null){thrownewIllegalArgumentException("Local and anonymous classes can not be ViewModels");}returnget(DEFAULT_KEY+":"+canonicalName,modelClass);}@MainThread

public <TextendsViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {ViewModel viewModel=mViewModelStore.get(key);if(modelClass.isInstance(viewModel)){if(mFactoryinstanceofOnRequeryFactory){((OnRequeryFactory)mFactory).onRequery(viewModel);}return(T)viewModel;}else{//noinspection StatementWithEmptyBodyif(viewModel!=null){// TODO: log a warning.}}if(mFactoryinstanceofKeyedFactory){viewModel=((KeyedFactory)mFactory).create(key,modelClass);}else{viewModel=mFactory.create(modelClass);}mViewModelStore.put(key,viewModel);return(T)viewModel;}

get()方法首先嘗試通過mViewModelStore的get()方法獲取ViewModel的實例,如果沒獲取到則使用mFactory的create()創(chuàng)建實例珍策,創(chuàng)建出來后則存入到mViewModelStore中托启。在這里mFactory就是ViewModel的構(gòu)造工廠,mViewModelStore則是ViewModel的緩存管理者攘宙。

ViewModelProvider作為ViewModel的提供者讲仰,使用緩存mViewModelStore和工廠mFactory實現(xiàn),第一次提供ViewModel時會通過工廠創(chuàng)建出來德召,后續(xù)則都是從緩存中拿贾费。

ViewModelStore

publicComponentActivity(){...getLifecycle().addObserver(newLifecycleEventObserver(){@OverridepublicvoidonStateChanged(@NonNullLifecycleOwnersource,@NonNullLifecycle.Eventevent){if(event==Lifecycle.Event.ON_DESTROY){if(!isChangingConfigurations()){getViewModelStore().clear();}}}});}@NonNull@OverridepublicViewModelStoregetViewModelStore(){if(getApplication()==null){thrownewIllegalStateException("Your activity is not yet attached to the "+"Application instance. You can't request ViewModel before onCreate call.");}if(mViewModelStore==null){NonConfigurationInstancesnc=(NonConfigurationInstances)getLastNonConfigurationInstance();if(nc!=null){// Restore the ViewModelStore from NonConfigurationInstancesmViewModelStore=nc.viewModelStore;}if(mViewModelStore==null){mViewModelStore=newViewModelStore();}}returnmViewModelStore;}

ViewModelStoreOwner接口getViewModelStore()的實現(xiàn)就是提供一個ViewModelStore實例,而ComponentActivity使用Lifecycle能力在頁面銷毀時調(diào)用ViewModelStore實例的clear方法,清空其中的ViewModel。

publicclassViewModelStore{privatefinalHashMap<String,ViewModel>mMap=newHashMap<>();finalvoidput(String key,ViewModel viewModel){ViewModel oldViewModel=mMap.put(key,viewModel);if(oldViewModel!=null){oldViewModel.onCleared();}}finalViewModelget(String key){returnmMap.get(key);}Set<String>keys(){returnnewHashSet<>(mMap.keySet());}/**

? ? *? Clears internal storage and notifies ViewModels that they are no longer used.

? ? */publicfinalvoidclear(){for(ViewModel vm:mMap.values()){vm.clear();}mMap.clear();}}

ViewModelStore中使用HashMap管理ViewModel緩存,它被頁面持有缓淹,并在頁面真正銷毀時才清空緩存。

官網(wǎng)的這張圖中可以說明ViewModel的生命周期工窍。

SaveStateViewModelFactory

publicViewModelProvider.FactorygetDefaultViewModelProviderFactory(){if(getApplication()==null){thrownewIllegalStateException("Your activity is not yet attached to the "+"Application instance. You can't request ViewModel before onCreate call.");}if(mDefaultFactory==null){mDefaultFactory=newSavedStateViewModelFactory(getApplication(),this,getIntent()!=null?getIntent().getExtras():null);}returnmDefaultFactory;}

ComponentActivity中g(shù)etDefaultViewModelProviderFactory()方法通過構(gòu)造方法創(chuàng)建一個SavedStateViewModelFactory對象割卖,傳入了Application、當(dāng)前ComponentActivity實例和Intent中的數(shù)據(jù)bundle患雏。

SavedStateViewModelFactory構(gòu)造方法

publicSavedStateViewModelFactory(@NonNullApplication application,@NonNullSavedStateRegistryOwner owner,@NullableBundle defaultArgs){mSavedStateRegistry=owner.getSavedStateRegistry();mLifecycle=owner.getLifecycle();mDefaultArgs=defaultArgs;mApplication=application;mFactory=ViewModelProvider.AndroidViewModelFactory.getInstance(application);}

構(gòu)造方法接受的參數(shù)中鹏溯,頁面實例是SavedStateRegistryOwner接口類型的,通過該接口獲取到SavedStateRegistry和Lifecycle淹仑。另外成員變量mFactory是AndroidViewModelFactory的單例對象丙挽。

SavedStateViewModelFactory的create()

@Overridepublic<TextendsViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {booleanisAndroidViewModel=AndroidViewModel.class.isAssignableFrom(modelClass);Constructor<T> constructor;

? ? if (isAndroidViewModel) {constructor=findMatchingConstructor(modelClass,ANDROID_VIEWMODEL_SIGNATURE);} else {constructor=findMatchingConstructor(modelClass,VIEWMODEL_SIGNATURE);}? ? // doesn't need SavedStateHandle

? ? if (constructor == null) {returnmFactory.create(modelClass);}? ? SavedStateHandleController controller = SavedStateHandleController.create(

? ? ? ? mSavedStateRegistry, mLifecycle, key, mDefaultArgs);

? ? try {Tviewmodel;if(isAndroidViewModel){viewmodel=constructor.newInstance(mApplication,controller.getHandle());}else{viewmodel=constructor.newInstance(controller.getHandle());}viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER,controller);returnviewmodel;} catch (IllegalAccessException e) {thrownewRuntimeException("Failed to access "+modelClass,e);} catch (InstantiationException e) {thrownewRuntimeException("A "+modelClass+" cannot be instantiated.",e);} catch (InvocationTargetException e) {thrownewRuntimeException("An exception happened in constructor of "+modelClass,e.getCause());}}

create()方法支持創(chuàng)建三種類型的ViewModel:AndroidViewModel、支持SavedState的ViewModel匀借、普通ViewModel颜阐,這里由于篇幅原因,只分析一下普通ViewModel的創(chuàng)建吓肋。普通ViewModel通過mFactory的create()方法創(chuàng)建出來凳怨。

AndroidViewModelFactory的create()

publicstaticclassAndroidViewModelFactoryextendsViewModelProvider.NewInstanceFactory{...@NonNull@Overridepublic<TextendsViewModel>Tcreate(@NonNullClass<T>modelClass){if(AndroidViewModel.class.isAssignableFrom(modelClass)){//noinspection TryWithIdenticalCatchestry{returnmodelClass.getConstructor(Application.class).newInstance(mApplication);}catch(NoSuchMethodExceptione){thrownewRuntimeException("Cannot create an instance of "+modelClass,e);}catch(IllegalAccessExceptione){thrownewRuntimeException("Cannot create an instance of "+modelClass,e);}catch(InstantiationExceptione){thrownewRuntimeException("Cannot create an instance of "+modelClass,e);}catch(InvocationTargetExceptione){thrownewRuntimeException("Cannot create an instance of "+modelClass,e);}}returnsuper.create(modelClass);}}

AndroidViewModelFactory的create()方法判斷如果不是AndroidViewModel類型,就直接通過父類的create()方法創(chuàng)建是鬼,而AndroidViewModelFactory的父類是NewInstanceFactory肤舞。

NewInstanceFactory的create()

publicstaticclassNewInstanceFactoryimplementsFactory{...@SuppressWarnings("ClassNewInstance")@NonNull@Overridepublic<TextendsViewModel>Tcreate(@NonNullClass<T>modelClass){//noinspection TryWithIdenticalCatchestry{returnmodelClass.newInstance();}catch(InstantiationExceptione){thrownewRuntimeException("Cannot create an instance of "+modelClass,e);}catch(IllegalAccessExceptione){thrownewRuntimeException("Cannot create an instance of "+modelClass,e);}}}

NewInstanceFactory的create()則是直接通過反射創(chuàng)建出ViewModel實例。

SaveStateViewModelFactory作為ComponentActivity和Fragment提供的對象均蜜,在NewInstanceFactory的基礎(chǔ)上增加了對AndroidViewModel和支持SavedStated的ViewModel的創(chuàng)建李剖,但對于普通的ViewModel創(chuàng)建,最后還是降級使用NewInstanceFactory完成囤耳。

到此篙顺,ViewModel的主要類已經(jīng)分析完了,接下來可以結(jié)合類關(guān)系充择,一定程度上總結(jié)出對全局視角的理解德玫。

主要類說明:

ViewModelProvider:ViewModel提供者

ViewModelStore:ViewModel緩存管理

ViewModelProvider.Factory:ViewModel創(chuàng)建工廠

SavedStateViewModelFactory:ViewModel創(chuàng)建工廠的實現(xiàn)

NewInstanceFactory:普通ViewModel創(chuàng)建工廠的實現(xiàn)

類關(guān)系描述:

ViewModel通過ViewModelProvider的get()方法獲取到,ViewModelProvider由緩存ViewModelStore和創(chuàng)建工廠ViewModelProvider.Factory組合而成聪铺,ViewModelStore和ViewModelProvider.Factory也是ComponentActivity的一部分化焕,ComponentActivity通過實現(xiàn)ViewModelStoreOwner和HasDefaultViewModelProviderFactory兩個接口對外提供ViewModelStore和ViewModelProvider.Factory。其中铃剔,ViewModelProvider.Factory在ComponentActivity的具體實現(xiàn)是SavedStateViewModelFactory撒桨,SavedStateViewModelFactory一部分由AndroidViewModelFactory組合而成,它提供創(chuàng)建三種ViewModel的能力键兜,其中普通ViewModel的創(chuàng)建是由AndroidViewModelFactory的父類NewInstanceFactory完成凤类。

逐類分析方法總結(jié)

逐類分析重點在于抓大放小,分析每個類的主要目的是掌握該類的功能定位普气,達(dá)到目的即可谜疤,不要深陷到源碼細(xì)節(jié)中。在快速分析完后现诀,結(jié)合相關(guān)的類做出總結(jié)夷磕,從而獲得整體上的了解,為以后進(jìn)一步源碼原理分析打好基礎(chǔ)仔沿。

源碼分析技巧

Android Jetpack是一個比較新的開源庫坐桩,有幾個技巧可以提高分析的效率,比如查看代碼提交記錄和使用單元測試封锉。

01查看代碼提交記錄

比如Lifecycling的lifecycleEventObserver()方法比較復(fù)雜绵跷,剛開始不太能理解這個方法封裝注解解析后的監(jiān)聽者那部分邏輯〕筛#可以使用以下方法查看這幾行的提交記錄碾局,方便理解。

查看Annotate:

點擊相關(guān)行奴艾,查看提交信息

雙擊相關(guān)類净当,查看改動記錄

在改動記錄中,還可以繼續(xù)查看Annotation蕴潦,理解原有的功能

可以使用該技巧先理解舊功能是什么樣的像啼,從而對比出這次改動所增加的特性。

以本例來說品擎,可以看出舊getObserverConstructorType()方法是直接返回構(gòu)造對象埋合,這個構(gòu)造對象可能是注解處理器生成的類的,也可能是普通監(jiān)聽者需要用反射處理的類的萄传,然后用這個構(gòu)造對象創(chuàng)建出監(jiān)聽器的封裝甚颂。而這次修改了getObserverConstructorType()返回為解析后的結(jié)果類型,包括REFLECTIVE_CALLBACK和GENERATED_CALLBACK秀菱,再用這個類型和getObserverConstructorType()方法中解析的緩存判斷應(yīng)該創(chuàng)建哪個監(jiān)聽器的封裝對象振诬。這次增加的功能點是對實現(xiàn)多個LifecycleObserver接口的監(jiān)聽器的支持,可以在單元測試類GeneratedAdapterTest中找到具體使用示例衍菱。

interfaceOnPausesextendsLifecycleObserver{@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)voidonPause();@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)voidonPause(LifecycleOwnerowner);}interfaceOnPauseResumeextendsLifecycleObserver{@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)voidonPause();@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)voidonResume();}classImpl1implementsOnPauses,OnPauseResume{List<String>mLog;Impl1(List<String>log){mLog=log;}@OverridepublicvoidonPause(){mLog.add("onPause_0");}@OverridepublicvoidonResume(){mLog.add("onResume");}@OverridepublicvoidonPause(LifecycleOwnerowner){mLog.add("onPause_1");}}

比如上面的Impl1實現(xiàn)了OnPauses和OnPauseResume兩個LifecycleObserver接口赶么,這次增加的功能點就是對Impl1也可以使用注解解析器生成封裝類,以優(yōu)化性能脊串。

02使用單元測試用例

JetPack中的單元測試非常豐富辫呻,而且從提交信息中一般都可以看到本次改動對應(yīng)修改的單元測試類清钥,比如上面的例子中,Commit

Message可以看到“Test:

GeneratedAdaptersTest”放闺,可以很快定位到該單元測試祟昭,再加上斷點調(diào)試的手段,更快地理解源碼怖侦。

比如篡悟,之前一直有提到注解解析器生成的監(jiān)聽器封裝類,那這個類具體代碼是什么樣的呢匾寝,就可以在GeneratedAdaptersTest找到使用注解的實例搬葬,再通過斷點找到這個類。

debug運行testOnAny()測試

通過堆椦藁冢可以定位到GeneratedAdaptersTest_TestObserver_LifecycleAdapter類急凰,

publicclassGeneratedAdaptersTest_TestObserver_LifecycleAdapterimplementsGeneratedAdapter{finalGeneratedAdaptersTest.TestObservermReceiver;GeneratedAdaptersTest_TestObserver_LifecycleAdapter(GeneratedAdaptersTest.TestObserverreceiver){this.mReceiver=receiver;}@OverridepublicvoidcallMethods(LifecycleOwnerowner,Lifecycle.Eventevent,booleanonAny,MethodCallsLoggerlogger){booleanhasLogger=logger!=null;if(onAny){if(!hasLogger||logger.approveCall("onAny",1)){mReceiver.onAny();}return;}if(event==Lifecycle.Event.ON_CREATE){if(!hasLogger||logger.approveCall("onCreate",1)){mReceiver.onCreate();}return;}}}

該類既是注解解析器生成的監(jiān)聽器封裝類,它的callMethods()方法的實現(xiàn)由TestObserver的注解決定很钓,TestObserver中使用了ON_CREATE和ON_ANY注解香府,所以除了onAny為true的情況,callMethods()只回調(diào)監(jiān)聽者的onCreate()方法码倦。

注解處理器的實現(xiàn)可以定位到lifecycle-compiler項目中看企孩,這里限于篇幅就不展開了。

總結(jié)

本文以Lifecycle袁稽、LiveData和ViewModel三個組件勿璃,分別介紹了自底向上、自頂向下和逐類分析三種分析方法推汽,以及查看代碼提交記錄和使用單元測試用例兩個簡單的技巧补疑。需要說明的是,分析方法和技巧都不是獨立的歹撒,比如逐類分析其實就是簡單版的自底向上莲组,只不過它更適合在對一個組件不太了解的情況下快速掌握大概原理,使用逐類分析掌握基本原理后暖夭,還可以繼續(xù)采用自頂向下的方法再分析一遍锹杈,以便更好地掌握組件的特性,減少實際工作中踩坑的可能迈着。

而在分析源碼后竭望,對分析方法和技巧做一些總結(jié),可以使得分析工作的效率越來越高裕菠。大家如果有其它想法和心得咬清,歡迎和我交流。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市旧烧,隨后出現(xiàn)的幾起案子影钉,更是在濱河造成了極大的恐慌,老刑警劉巖粪滤,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斧拍,死亡現(xiàn)場離奇詭異雀扶,居然都是意外死亡杖小,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門愚墓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來予权,“玉大人,你說我怎么就攤上這事浪册∩ㄏ伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵村象,是天一觀的道長笆环。 經(jīng)常有香客問我,道長厚者,這世上最難降的妖魔是什么躁劣? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮库菲,結(jié)果婚禮上账忘,老公的妹妹穿的比我還像新娘。我一直安慰自己熙宇,他們只是感情好鳖擒,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烫止,像睡著了一般蒋荚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上馆蠕,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天期升,我揣著相機(jī)與錄音,去河邊找鬼荆几。 笑死吓妆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吨铸。 我是一名探鬼主播行拢,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诞吱!你這毒婦竟也來了舟奠?” 一聲冷哼從身側(cè)響起竭缝,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沼瘫,沒想到半個月后抬纸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡耿戚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年湿故,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膜蛔。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡坛猪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出皂股,到底是詐尸還是另有隱情墅茉,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布呜呐,位于F島的核電站就斤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蘑辑。R本人自食惡果不足惜洋机,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望以躯。 院中可真熱鬧槐秧,春花似錦、人聲如沸忧设。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽址晕。三九已至膀懈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谨垃,已是汗流浹背启搂。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留刘陶,地道東北人胳赌。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像匙隔,于是被迫代替她去往敵國和親疑苫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容