Android 基礎(chǔ) -- Activity 生命周期實(shí)踐總結(jié)

Activity / Fragment 的生命周期是每個(gè) Android 開發(fā)者最最基礎(chǔ)的知識(shí)點(diǎn)供嚎。所以特別有必要自己整理一番。總看別人博客和書上的死知識(shí)槽驶,還不如自己動(dòng)手實(shí)踐审洞,然后輸出要印象深刻,理解透徹痕支。

Activity 生命周期

正常情況下的生命周期分析

  1. 針對一個(gè)特定的 Activity 颁虐,第一次啟動(dòng),回調(diào)如下:onCreate —-> onStart —-> onResume

Log 日志
D/KLog: (MainActivity.java:19) onCreate
D/KLog: (MainActivity.java:44) onStart
D/KLog: (MainActivity.java:62) onResume

  1. 切換回到桌面的時(shí)候卧须,回調(diào)如下:onPause —-> onStop

Log 日志
D/KLog: (MainActivity.java:50) onPause
D/KLog: (MainActivity.java:68) onStop

  1. Back 鍵退出的話另绩,最后會(huì) onDestroy

  2. 啟動(dòng)一個(gè)新的 Activity , 我們看看兩個(gè) Activity 的生命周期:

Log 日志
D/KLog: (MainActivity.java:50) onPause
D/KLog: (OtherActivity.java:25) onCreate
D/KLog: (OtherActivity.java:31) onStart
D/KLog: (OtherActivity.java:49) onResume
D/KLog: (MainActivity.java:68) onStop
可以得到順序是:onPause(A) —-> onCreate(B) —-> onStart(B) —-> onResume(B) —-> onStop(A)

  1. 這個(gè)時(shí)候我們 Back 回到第一個(gè) Activity 時(shí)發(fā)生的回調(diào):

Log 日志
D/KLog: (OtherActivity.java:37) onPause
D/KLog: (MainActivity.java:56) onRestart
D/KLog: (MainActivity.java:44) onStart
D/KLog: (MainActivity.java:62) onResume
D/KLog: (OtherActivity.java:55) onStop
D/KLog: (OtherActivity.java:61) onDestroy
可以得到順序是: onPause(B) —-> onRestart(A) —-> onStart(A) —-> onResume(A) —-> onStop(B) —-> onDestroy(B)

  1. 如果我在 B Activity 中的 onCreate 回調(diào)中直接 finish()

Log 日志
D/KLog: (MainActivity.java:50) onPause
D/KLog: (OtherActivity.java:25) onCreate
D/KLog: (MainActivity.java:62) onResume
D/KLog: (OtherActivity.java:62) onDestroy
我們發(fā)現(xiàn) B Activity 只會(huì)執(zhí)行 onCreateonDestroy

  1. 接下來我們啟動(dòng)一個(gè)特殊的 Activity (半透明或者對話框樣式)到關(guān)閉它:

Log 日志
D/MainActivity: onPause
D/DialogActivity: onCreate
D/DialogActivity: onStart
D/DialogActivity: onResume
D/DialogActivity: onPause
D/MainActivity: onResume
D/DialogActivity: onStop
D/DialogActivity: onDestroy

在正常使用應(yīng)用的過程中花嘶,前臺(tái) Activity 有時(shí)會(huì)被其他導(dǎo)致 Activity 暫停的可視組件阻擋笋籽。 例如,當(dāng)半透明 Activity 打開時(shí)(比如對話框樣式中的 Activity )椭员,上一個(gè) Activity 會(huì)暫停车海。 只要 Activity 仍然部分可見但目前又未處于焦點(diǎn)之中,它會(huì)一直暫停拆撼。

<div class="tip">
問題:如果是啟動(dòng)一個(gè)普通的 Dialog 容劳,Activity 的會(huì)執(zhí)行 onPause 嗎?
</div>

答案是不會(huì)的闸度,我們可以這樣理解竭贩,普通的 dialog 是依附在本 Activity 的,相當(dāng)于是一個(gè)整體莺禁,所以它本身的焦點(diǎn)也是屬于 Activity 的留量。故不會(huì)調(diào)用 onPause 。

異常狀態(tài)下的生命周期

onSaveInstanceState 方法只會(huì)出現(xiàn)在 Activity 被異常終止的情況下哟冬,它的調(diào)用時(shí)機(jī)是在 onStop 之前楼熄,它和 onPause 方法沒有既定的時(shí)序關(guān)系,可能在它之前浩峡,也可能在它之后可岂。當(dāng) Activity 被重新創(chuàng)建的時(shí)候, onRestoreInstanceState 會(huì)被回調(diào)翰灾,它的調(diào)用時(shí)機(jī)是 onStart 之后缕粹。
系統(tǒng)只會(huì)在 Activity 即將被銷毀并且有機(jī)會(huì)重新顯示的情況下才會(huì)去調(diào)用 onSaveInstanceState 方法稚茅。
當(dāng) Activity 在異常情況下需要重新創(chuàng)建時(shí),系統(tǒng)會(huì)默認(rèn)為我們保存當(dāng)前 Activity 的視圖結(jié)構(gòu)平斩,并且在 Activity 重啟后為我們恢復(fù)這些數(shù)據(jù)亚享,比如文本框中用戶輸入的數(shù)據(jù)、listview 滾動(dòng)的位置等绘面,這些 view 相關(guān)的狀態(tài)系統(tǒng)都會(huì)默認(rèn)為我們恢復(fù)欺税。具體針對某一個(gè) view 系統(tǒng)能為我們恢復(fù)哪些數(shù)據(jù)可以查看 view 的源碼中的 onSaveInstanceStateonRestoreInstanceState 方法。

Demo 代碼:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    KLog.d(getClass().getSimpleName(),"onSaveInstanceState");
    outState.putString(STATE, "test");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    KLog.d(getClass().getSimpleName(),"[onRestoreInstanceState]: " + savedInstanceState.getString(STATE));
}

為了方便我們旋轉(zhuǎn)下屏幕來異常終止 Activity :

Log 日志
D/MainActivity: onPause
D/MainActivity: onSaveInstanceState
D/MainActivity: onStop
D/MainActivity: onDestroy
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: [onRestoreInstanceState]: test
D/MainActivity: onResume

摘自 Android 開發(fā)者藝術(shù)探索 一書:

關(guān)于保存和恢復(fù) View 的層次結(jié)構(gòu)揭璃,系統(tǒng)工作流程是: Activity 異常終止, Activity 調(diào)用 onSaveInstanceState 去保存數(shù)據(jù)晚凿,然后 Activity 會(huì)委托 Windows 去保存數(shù)據(jù),接著 Window 再委托它上面的頂層容器去保存數(shù)據(jù)塘辅。頂層容器是一個(gè) ViewGroup 晃虫,一般來說它很可能是 DectorView ,最后頂層容器再去通知它的子元素保存數(shù)據(jù)扣墩。(這是一種委托思想哲银,上層委托下層,父容器委托子元素去處理事情呻惕,如 View 的繪制過程荆责,事件分發(fā)都是采用類似的思想)

Fragment

普通的 Fragment

從圖可以看出,F(xiàn)ragment 生命周期大部分的狀態(tài)與 Activity 相似亚脆,特殊的是

  • onAttach() —— 當(dāng) Fragment 被加入到 Activity 時(shí)調(diào)用(在這個(gè)方法中可以獲得所在的 Activity ).
  • onCreateView() —— 當(dāng) Activity 要得到 Fragment 的 Layout 時(shí)做院,調(diào)用此方法,F(xiàn)ragment 在其中創(chuàng)建自己的 Layout (界面)濒持。
  • onActivityCreated() —— 當(dāng) Activity 的 onCreated() 方法返回后調(diào)用此方法
  • onDestroyView() —— 當(dāng) Fragment 中的視圖被移除的時(shí)候键耕,調(diào)用這個(gè)方法。
  • onDetach() —— 當(dāng) Fragment 和 Activity 分離的時(shí)候柑营,調(diào)用這個(gè)方法屈雄。

ViewPager 中的 Fragment

我們開發(fā)中經(jīng)常會(huì)用到 ViewPager + Fragment 組合的形式來完成特定的需求。本身 Fragment 生命周期就比 Activity 要復(fù)雜很多官套,當(dāng)它在 ViewPager 中又是怎么回調(diào)呢酒奶?

我先給 ViewPager 加入三個(gè) Fragment:

viewPager = (ViewPager) findViewById(R.id.viewpager);
fragmentList.add(new OneTextFragment());
fragmentList.add(new TwoTextFragment());
fragmentList.add(new ThreeTextFragment());
viewPager.setAdapter(new FtAdapter(getSupportFragmentManager(), fragmentList));

啟動(dòng)這個(gè) Activity 的日志如下:

D/ViewPagerHostActivity: onCreate
D/ViewPagerHostActivity: onStart
D/ViewPagerHostActivity: onResume
D/OneTextFragment: onAttach
D/OneTextFragment: onCreate
D/TwoTextFragment: onAttach
D/TwoTextFragment: onCreate
D/TwoTextFragment: onActivityCreated
D/OneTextFragment: onActivityCreated
D/OneTextFragment: onStart
D/OneTextFragment: onResume
D/TwoTextFragment: onStart
D/TwoTextFragment: onResume

我們發(fā)現(xiàn)啟動(dòng)后,有兩個(gè) Fragment(one,two) 被創(chuàng)建奶赔,為什么會(huì)創(chuàng)建兩個(gè)惋嚎?這個(gè)問題我們留著后面說。

當(dāng) Activity 進(jìn)入后臺(tái):

D/ViewPagerHostActivity: onPause
D/ViewPagerHostActivity: onSaveInstanceState
D/TwoTextFragment: onStop
D/OneTextFragment: onStop
D/ViewPagerHostActivity: onStop

當(dāng) Activity 返回前臺(tái):

D/ViewPagerHostActivity: onRestart
D/TwoTextFragment: onStart
D/OneTextFragment: onStart
D/ViewPagerHostActivity: onStart
D/ViewPagerHostActivity: onResume
D/TwoTextFragment: onResume
D/OneTextFragment: onResume

當(dāng) Activity 銷毀:

D/ViewPagerHostActivity: onPause
D/TwoTextFragment: onStop
D/OneTextFragment: onStop
D/ViewPagerHostActivity: onStop
D/TwoTextFragment: onDestroyView
D/TwoTextFragment: onDestroy
D/TwoTextFragment: onDetach
D/OneTextFragment: onDestroyView
D/OneTextFragment: onDestroy
D/OneTextFragment: onDetach
D/ViewPagerHostActivity: onDestroy

滑動(dòng)一頁:

D/ThreeTextFragment: onAttach
D/ThreeTextFragment: onCreate
D/ThreeTextFragment: onActivityCreated
D/ThreeTextFragment: onStart
D/ThreeTextFragment: onResume

當(dāng)前顯示的頁面是 TwoTextFragment 然后 ThreeTextFragment 也已經(jīng)創(chuàng)建好了站刑。

再滑動(dòng)一頁:

D/OneTextFragment: onStop
D/OneTextFragment: onDestroyView

當(dāng)前顯示的頁面是 ThreeTextFragment 另伍,我們發(fā)現(xiàn) OneTextFragment 已經(jīng)銷毀。

我們可以得到默認(rèn)狀態(tài)下的 ViewPager 會(huì)緩存 1 個(gè) Fragment绞旅,相當(dāng)于有兩個(gè) Fragment 是創(chuàng)建狀態(tài)摆尝。
當(dāng)我們增加一行代碼:

viewPager.setOffscreenPageLimit(2);

當(dāng) Activity 創(chuàng)建時(shí)的生命周期:

D/ViewPagerHostActivity: onCreate
D/ViewPagerHostActivity: onStart
D/ViewPagerHostActivity: onResume
D/OneTextFragment: onAttach
D/OneTextFragment: onCreate
D/TwoTextFragment: onAttach
D/TwoTextFragment: onCreate
D/ThreeTextFragment: onAttach
D/ThreeTextFragment: onCreate
D/TwoTextFragment: onActivityCreated
D/OneTextFragment: onActivityCreated
D/OneTextFragment: onStart
D/OneTextFragment: onResume
D/TwoTextFragment: onStart
D/TwoTextFragment: onResume
D/ThreeTextFragment: onStart
D/ThreeTextFragment: onResume

三個(gè) Fragment 都創(chuàng)建好了愕宋,并且左右切換不會(huì)走任何生命周期(雖然是廢話)。

setOffscreenPageLimit 源碼:

public void setOffscreenPageLimit(int limit) {
    if (limit < DEFAULT_OFFSCREEN_PAGES) {
        Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                DEFAULT_OFFSCREEN_PAGES);
        limit = DEFAULT_OFFSCREEN_PAGES;
    }
    if (limit != mOffscreenPageLimit) {
        mOffscreenPageLimit = limit;
        populate();
    }
}

通過源碼我們可以知道结榄,ViewPager 的緩存的默認(rèn)值和最小值是 1

啟動(dòng)模式

Activity 的四種啟動(dòng)模式

  • Standard:標(biāo)準(zhǔn)模式囤捻,一調(diào)用 startActivity() 方法就會(huì)產(chǎn)生一個(gè)新的實(shí)例臼朗。

  • SingleTop: 來了 intent, 每次都創(chuàng)建新的實(shí)例,僅一個(gè)例外:當(dāng)棧頂?shù)腶ctivity 恰恰就是該activity的實(shí)例(即需要?jiǎng)?chuàng)建的實(shí)例)時(shí)蝎土,不再創(chuàng)建新實(shí)例视哑。這解決了棧頂復(fù)用問題

  • SingleTask: 來了 intent 后,檢查棧中是否存在該 activity的實(shí)例誊涯,如果存在就把 intent 發(fā)送給它挡毅,否則就創(chuàng)建一個(gè)新的該activity的實(shí)例,放入一個(gè)新的 task 棧的棧底暴构」虺剩肯定位于一個(gè) task 的棧底,而且棧中只能有它一個(gè)該 activity 實(shí)例取逾,但允許其他 activity 加入該棧耗绿。解決了在一個(gè) task 中共享一個(gè) activity。

  • SingleInstance: 這個(gè)跟 SingleTask 基本上是一樣砾隅,只有一個(gè)區(qū)別:在這個(gè)模式下的Activity實(shí)例所處的task中误阻,只能有這個(gè)activity實(shí)例,不能有其他的實(shí)例晴埂。一旦該模式的activity的實(shí)例已經(jīng)存在于某個(gè)棧中究反,任何應(yīng)用在激活該activity時(shí)都會(huì)重用該棧中的實(shí)例,解決了多個(gè)task共享一個(gè) activity儒洛。

這些啟動(dòng)模式可以在功能清單文件 AndroidManifest.xml 中進(jìn)行設(shè)置精耐,中的 launchMode 屬性。

具體實(shí)踐

  • SingleTop 棧頂復(fù)用模式
<activity android:name=".dLaunchChapter.OneActivity"
    android:launchMode="singleTop"/>

我們在清單里先給 OneActivity 啟動(dòng)模式設(shè)置為 singleTop 晶丘,然后代碼啟動(dòng)活動(dòng)的順序?yàn)?One --> One黍氮,反復(fù)點(diǎn)擊多次,然后我們看看棧內(nèi)情況浅浮。

adb 命令 :dumpsys activity | grep -i run

root@vbox86p:/ # dumpsys activity | grep -i run
    Running activities (most recent first):
        Run #1: ActivityRecord{23e3b5b u0 com.hugo.demo.activitydemo/.dLaunchChapter.OneActivity t595}
        Run #0: ActivityRecord{1a2c6f3 u0 com.hugo.demo.activitydemo/.LaunchActivity t595}

該啟動(dòng)模式下并且 OneActivity 在棧頂所以不會(huì)創(chuàng)建新的實(shí)例沫浆,其生命周期調(diào)用 onPause —-> onNewIntent —-> onResume

  • SingleTask 棧內(nèi)復(fù)用模式

修改 OneActivity 的啟動(dòng)模式為 SingleTask ,然后我們代碼啟動(dòng)的順序?yàn)?One —-> Two —-> One滚秩,接了下看看棧內(nèi)情況:

One —-> Two 我們記錄下當(dāng)前的 Activity 棧:

Running activities (most recent first):
        Run #2: ActivityRecord{1e8701b7 u0 com.hugo.demo.activitydemo/.dLaunchChapter.TwoActivity t632}
        Run #1: ActivityRecord{39e11719 u0 com.hugo.demo.activitydemo/.dLaunchChapter.OneActivity t632}

接下來我們執(zhí)行 Two —-> One 专执,當(dāng)前 Activity 棧信息:

Running activities (most recent first):
       Run #1: ActivityRecord{39e11719 u0 com.hugo.demo.activitydemo/.dLaunchChapter.OneActivity t632}

當(dāng) TwoActivity 啟動(dòng) OneActivity(SingleTask) 的時(shí)候,堆棧信息里只剩下了 OneActivity 并且和第一次內(nèi)存信息 39e11719 相同郁油,所以確實(shí)是復(fù)用了沒有新建實(shí)例本股,接下來我們看看 Log 日志攀痊,再驗(yàn)證下我們的猜想,看看具體走了哪些生命周期:

D/TwoActivity: onPause
D/OneActivity: onNewIntent
D/OneActivity: onRestart
D/OneActivity: onStart
D/OneActivity: onResume
D/TwoActivity: onStop
D/TwoActivity: onDestroy

果然此時(shí) OneActivity 沒有重新創(chuàng)建拄显,并且系統(tǒng)把它切換到了棧頂并調(diào)用 onNewIntent 方法苟径,同時(shí)我們發(fā)現(xiàn), SingleTask 默認(rèn)具有 clearTop 效果躬审,導(dǎo)致 TwoActivity 出棧棘街。

<div class="tip">
我們代碼指定 OneActivity 的棧,效果還是一樣的嗎承边?
</div>

帶著問題我們修改下代碼遭殉,增加一行:

<activity
    android:name=".dLaunchChapter.OneActivity"
    android:launchMode="singleTask"
    android:taskAffinity="com.hugo.demo.singleTask"/>

然后我們按照剛剛順序 One —-> Two —-> One 啟動(dòng) Activity ,現(xiàn)在的棧內(nèi)信息還會(huì)更上次一樣嗎博助?

Running activities (most recent first):
        Run #2: ActivityRecord{1bc18519 u0 com.hugo.demo.activitydemo/.dLaunchChapter.OneActivity t636}
        Run #1: ActivityRecord{36e5e368 u0 com.hugo.demo.activitydemo/.dLaunchChapter.TwoActivity t635}

我們發(fā)現(xiàn)险污,雖然是復(fù)用了 OneActivity 而且移到了棧頂,但是并沒有銷毀 TwoActivity 富岳。

原因在于 singleTask 模式受 taskAffinity 影響蛔糯,TwoActivity 和 OneActivity 所在的 Activity 棧不同。

總結(jié)窖式,啟動(dòng)一個(gè) lauchMode 為 singleTask 的 Activity 時(shí)有兩種情況:

  1. 若系統(tǒng)中存在相同 taskAffinity 值的任務(wù)棧 (tacks1 )時(shí),會(huì)把 task1 從后臺(tái)調(diào)到前臺(tái)渤闷,若實(shí)例存在則干掉其上面的所有 Activity 并調(diào)用 onNewInstance 方法重用,沒有該實(shí)例則新建一個(gè)脖镀。
  2. 否則飒箭,新建一個(gè)任務(wù)棧,并以此 Activity 作為 root 蜒灰。
  • SingleInstance 單實(shí)例模式

這是一種加強(qiáng)的 singleTask 模式弦蹂,它除了具有 singleTask 模式的所有特性以外,還加強(qiáng)了一點(diǎn)强窖,就是具有此模式的 Activity 只能單獨(dú)地位于任務(wù)棧凸椿。

<div class="tip">
好了,關(guān)于生命周期和啟動(dòng)模式實(shí)踐+知識(shí)點(diǎn)整理已經(jīng)完成啦翅溺,
非常推薦大家下載源碼自己運(yùn)行看看 Log 日志脑漫,查看源碼:Github
,這樣可以對這篇文章知識(shí)更加深刻咙崎。
</div>

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末优幸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子褪猛,更是在濱河造成了極大的恐慌网杆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碳却,居然都是意外死亡队秩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門昼浦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馍资,“玉大人,你說我怎么就攤上這事关噪∶灾模” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵色洞,是天一觀的道長。 經(jīng)常有香客問我冠胯,道長火诸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任荠察,我火速辦了婚禮置蜀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悉盆。我一直安慰自己盯荤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布焕盟。 她就那樣靜靜地躺著秋秤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脚翘。 梳的紋絲不亂的頭發(fā)上灼卢,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音来农,去河邊找鬼鞋真。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沃于,可吹牛的內(nèi)容都是我干的涩咖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼繁莹,長吁一口氣:“原來是場噩夢啊……” “哼檩互!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咨演,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤盾似,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體零院,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溉跃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了告抄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撰茎。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖打洼,靈堂內(nèi)的尸體忽然破棺而出龄糊,到底是詐尸還是另有隱情,我是刑警寧澤募疮,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布炫惩,位于F島的核電站,受9級特大地震影響阿浓,放射性物質(zhì)發(fā)生泄漏他嚷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一芭毙、第九天 我趴在偏房一處隱蔽的房頂上張望筋蓖。 院中可真熱鬧,春花似錦退敦、人聲如沸粘咖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓮下。三九已至,卻和暖如春钝域,著一層夾襖步出監(jiān)牢的瞬間唱捣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工网梢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留震缭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓战虏,卻偏偏與公主長得像拣宰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子烦感,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

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