深入理解AAC架構(gòu) - Lifecycle整體機(jī)制源碼

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)類為ComponentActivityFragment,兩者提供的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)拓颓,而主要包括:

    1. 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適配類适室,以減少反射消耗嫡意,典型的空間換時間。

    2. 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)坎怪。

    3. 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注解都會失效拟枚。

    4. LifecycleEventObserver
      LifecycleObserver子接口薪铜。只有一個onStateChanged方法,以Lifecycle.Event入?yún)⑻峁┦录^(qū)分的形式恩溅,進(jìn)行統(tǒng)一方法回調(diào)隔箍。
      FullLifecycleObserver不沖突,但是也會無效化@OnLifecycleEvent注解脚乡。
      同時實(shí)現(xiàn)LifecycleEventObserverFullLifecycleObserver蜒滩,可以得到2次相同的生命周期回調(diào),后者的具體方法回調(diào)優(yōu)先于前者的統(tǒng)一方法回調(diào)奶稠。

    5. ReflectiveGenericLifecycleObserver
      LifecycleEventObserver子類俯艰。適應(yīng)于注解方式的反射工作方式。
      通過該類對觀察者進(jìn)行包裝锌订,處理觀察者關(guān)注的回調(diào)的反射調(diào)用竹握,由Lifecycling處理包裝過程。

    6. SingleGeneratedAdapterObserver
      LifecycleEventObserver子類辆飘。適應(yīng)于注解方式的預(yù)編譯工作方式啦辐。
      通過該類對觀察者的GeneratedAdapter進(jìn)行包裝,處理GeneratedAdapter的方法調(diào)用蜈项,由Lifecycling處理包裝過程芹关。

    7. 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引入前飘蚯,LifecycleOwnerFragmentActivity實(shí)現(xiàn)。引入后福也,遷移到alpha01中新增的ComponentActivity局骤。

不直接在ComponentActivityLifecycleRegistry進(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

ProcessLifecycleOwnerLifecycleDispatcher
需要引入 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.initProcessLifecycleOwnerInitializer調(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)多律。

在不同版本, ReportFragmentActivity的偵測方法實(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)和事件可以參考下圖:


https://developer.android.google.cn/topic/libraries/architecture/lifecycle

LifecycleRegistry 成員變量:

  1. mObserverMap:
    Observer列表骡湖,采用FastSafeIterableMap,key為Observer峻厚,value為對Observer的封裝對象ObserverWithState响蕴。ObserverWithState在持有Observer的同時,保存了Observer對應(yīng)的狀態(tài)惠桃。

    LiveData也是類似的實(shí)現(xiàn)浦夷。

    FastSafeIterableMapSafeIterableMap的子類,本質(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)的能力收班。

  2. mState
    當(dāng)前LifecycleRegistry的生命周期狀態(tài)坟岔。

  3. mLifecycleOwner
    當(dāng)前對應(yīng)的生命周期提供者,使用弱引用防止內(nèi)存泄漏闺阱。

  4. mAddingObserverCounter
    記錄正在初始化同步的新添加Observer的數(shù)量炮车,大于0時,表示正在對新添加的Observer進(jìn)行初始化同步。
    防止addObserver()重入時瘦穆,多次調(diào)用sync()纪隙。使sync()僅僅在最外層的addObserver()同步邏輯完成后執(zhí)行一次。

  5. mHandlingEvent
    標(biāo)記正在進(jìn)行狀態(tài)事件同步扛或。
    防止moveToState()重入時绵咱,多次調(diào)用sync()

  6. mNewEventOccurred
    標(biāo)記發(fā)生事件嵌套熙兔。
    主要作用在moveToState()重入時悲伶,將mNewEventOccurred設(shè)置為true,打斷正在發(fā)生的sync()同步邏輯住涉,并重新執(zhí)行麸锉。

  7. mParentStates
    用于解決addObserver()過程中可能發(fā)生的remove+add,保證鏈表的不變式成立舆声。

從上可以分析出花沉,LifecycleRegistry的存在兩種同步邏輯:

  1. 對新添加的Observer進(jìn)行初始化同步,在添加Observer時調(diào)用addObserver()觸發(fā)媳握。
  2. 對所有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個, 分別是

  1. setCurrentState(State state) :遷移到傳入的指定狀態(tài)
  2. 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ì)了mAddingObserverCountermHandlingEvent脆栋,mNewEventOccurred倦卖,主要是確保sync()只在最頂層執(zhí)行同步,以免出現(xiàn)同步錯誤椿争。

在調(diào)用sync()之前怕膛,通過判斷mAddingObserverCounter != 0mHandlingEvent判斷sync()是否需要執(zhí)行:

  1. mHandlingEvent = true
    表示正在進(jìn)行狀態(tài)事件同步,此時sync()正在執(zhí)行秦踪,無需再次調(diào)用褐捻。

    moveToState(state1)
    ->  sync()
    ->  moveToState(state2)
        ->  sync()              // 無需執(zhí)行
    
    moveToState(state1)
    ->  sync()
    ->  addObserver()
        ->  sync()              // 無需執(zhí)行
    
  2. 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,這個ObserveronStart()中希坚,從鏈表中移除边苹,且添加一個新的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提供的Fragmentandroidx.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的生命周期方法中阅悍,通過FragmentControllerFragmentManagerImpl局嘁,最終調(diào)用Fragment中相應(yīng)的生命周期方法。
由于涉及的源碼數(shù)量較多且比較簡單晦墙,此處不貼出源碼悦昵。

回調(diào)順序

需要注意的是,除了onCreate()晌畅、onResume()外但指,FragmentActivityFragmentController的調(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)該會用于管理FragmentLifecycleRegistry對象绰播。

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的分析骄噪。
水平有限,如有錯誤蠢箩,歡迎指正链蕊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谬泌,隨后出現(xiàn)的幾起案子滔韵,更是在濱河造成了極大的恐慌,老刑警劉巖呵萨,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奏属,死亡現(xiàn)場離奇詭異,居然都是意外死亡潮峦,警方通過查閱死者的電腦和手機(jī)囱皿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忱嘹,“玉大人嘱腥,你說我怎么就攤上這事【性茫” “怎么了齿兔?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長础米。 經(jīng)常有香客問我分苇,道長,這世上最難降的妖魔是什么屁桑? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任医寿,我火速辦了婚禮,結(jié)果婚禮上蘑斧,老公的妹妹穿的比我還像新娘靖秩。我一直安慰自己,他們只是感情好竖瘾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布沟突。 她就那樣靜靜地躺著,像睡著了一般捕传。 火紅的嫁衣襯著肌膚如雪惠拭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天庸论,我揣著相機(jī)與錄音求橄,去河邊找鬼今野。 笑死,一個胖子當(dāng)著我的面吹牛罐农,可吹牛的內(nèi)容都是我干的条霜。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼涵亏,長吁一口氣:“原來是場噩夢啊……” “哼宰睡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起气筋,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤拆内,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宠默,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體麸恍,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年搀矫,在試婚紗的時候發(fā)現(xiàn)自己被綠了抹沪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓤球,死狀恐怖融欧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卦羡,我是刑警寧澤噪馏,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站绿饵,受9級特大地震影響欠肾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拟赊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一刺桃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧要门,春花似錦虏肾、人聲如沸廓啊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谴轮。三九已至炒瘟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間第步,已是汗流浹背疮装。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工缘琅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人廓推。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓刷袍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親樊展。 傳聞我的和親對象是個殘疾皇子呻纹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345