Android應(yīng)用啟動(dòng)流程分析

1.應(yīng)用啟動(dòng)流程分析:

1.1流程

一個(gè)Activity的啟動(dòng)過程。以Launcher中啟動(dòng)一個(gè)App為例,比如在Launcher中我們點(diǎn)了一個(gè)圖標(biāo)啟動(dòng)一個(gè)App的Activity径缅,Launcher里會(huì)執(zhí)行:

Intent intent = new Intent("xxx");

startActivity(intent);

簡(jiǎn)單的說下大體流程溜哮,App與AMS交互流程主要分以下幾步:

1. 原App通知AMS要起一個(gè)新Activity。

2. AMS創(chuàng)建相應(yīng)數(shù)據(jù)結(jié)構(gòu)塘砸,然后通知WMS創(chuàng)建相應(yīng)數(shù)據(jù)結(jié)構(gòu),再通知原Activity暫停。

3. 原Activity暫停后通知AMS嗓奢。

4. AMS創(chuàng)建新App進(jìn)程,通知WMS新App可見浑厚,再通知App創(chuàng)建Activity等相應(yīng)數(shù)據(jù)結(jié)構(gòu)股耽。

首先分析下App端的結(jié)構(gòu)。移動(dòng)平臺(tái)一般顯示區(qū)域有限钳幅,要完成一個(gè)工作往往不是一屏內(nèi)容中能搞定的物蝙,所以Android中有了Activity的概念,讓用戶可以把相關(guān)的子內(nèi)容放到單獨(dú)的Activity中敢艰,然后通過Intent在Activity間跳轉(zhuǎn)诬乞。類似于瀏覽網(wǎng)頁,點(diǎn)擊鏈接跳轉(zhuǎn)到另一個(gè)網(wǎng)頁。這些同一交互過程中的一系列Activity成為一個(gè)Task丽惭。這些Activity運(yùn)行在主線程ActivityThread中击奶。Activity要展現(xiàn)出來的主視圖是DecorView,它是一棵視圖樹责掏。ViewRootImpl負(fù)責(zé)管理這個(gè)視圖樹和與WMS交互柜砾,與WMS交互通過WindowManagerImpl和WindowManagerGlobal。DecorView被包含在系統(tǒng)的通用窗口抽象類Window當(dāng)中换衬。視圖對(duì)應(yīng)的圖形緩沖區(qū)由Surface管理痰驱。

1.2主要類介紹

其中涉及到的主要的類包括下面幾個(gè):

AMS(ActivityManagerService)

Activity的管理者。其實(shí)除了Activity瞳浦,AMS也管Service等組件信息担映,另外AMS還管理Process信息。

Activity:描述一個(gè)Activity叫潦,它是與用戶交互的基本單元蝇完。

ActivityRecord:描述單個(gè)Activity,Activity堆棧中的基本單元矗蕊。

ActivityThread:每一個(gè)App進(jìn)程有一個(gè)主線程短蜕,它由ActivityThread描述。它負(fù)責(zé)這個(gè)App進(jìn)程中各個(gè)Activity的調(diào)度和執(zhí)行傻咖,以及響應(yīng)AMS的操作請(qǐng)求等朋魔。

ApplicationThread:AMS和Activity通過它進(jìn)行通信。對(duì)于AMS而言卿操,ApplicationThread代表了App的主線程警检。簡(jiǎn)而言之,它是AMS與ActivityThread進(jìn)行交互的接口害淤。注意ActivityThread和ApplicationThread之間的關(guān)系并不像Activity與Application扇雕。后者的關(guān)系是Application中包含了多個(gè)Activity,而前者ActivityThread和ApplicationThread是同一個(gè)東西的兩種"View"窥摄,ApplicationThread是在AMS眼中的ActivityThread洼裤。

ProcessRecord:描述一個(gè)App進(jìn)程,包含了該進(jìn)程中的Activity和Service列表溪王。

TaskRecord:TaskRecord中的mActivities是ActivityRecord的列表,它們是按照歷史順序排序的值骇。

ActivityStack:Activity堆棧莹菱,其中的ActivityRecord是通過TaskRecord這一層間接地被管理著。

ActivityStackSupervisor:ActivityStackSupervisor是ActivityStack的總管吱瘩。4.4中默認(rèn)引入了兩個(gè)ActivityStack道伟,一個(gè)叫Home stack,放Launcher和systemui,id為0蜜徽;另一個(gè)是Applicationstack祝懂,放App的Activity,id可能是任意值拘鞋。

ViewRootImpl:主要責(zé)任包括創(chuàng)建Surface砚蓬,和WMS的交互和App端的UI布局和渲染。同時(shí)負(fù)責(zé)把一些事件發(fā)往Activity以便Activity可以截獲事件盆色。每一個(gè)添加到WMS中的窗口對(duì)應(yīng)一個(gè)ViewRootImpl灰蛙,通過WindowManagerGlobal向WMS添加窗口時(shí)創(chuàng)建。大多數(shù)情況下隔躲,它管理Activity頂層視圖DecorView摩梧。總得來說宣旱,它相當(dāng)于MVC模型中的Controller仅父。

ViewRootImpl::W:用于向WMS提供接口,讓W(xué)MS控制App端的窗口浑吟。它可看作是個(gè)代理笙纤,很多時(shí)候會(huì)調(diào)用ViewRootImpl中的功能。這種內(nèi)嵌類的用法很多买置,特別是這種提供接口的代理類粪糙,如PhoneWindow::DecorView等。

Instrumentation:官方提供的Hook忿项,主要用于測(cè)試蓉冈。如果只關(guān)注窗口管理流程的話可以先無視。

WindowManagerImpl:Activity中與窗口管理系統(tǒng)通信的代理類轩触,實(shí)現(xiàn)類是WindowManagerGlobal寞酿。WindowManagerGlobal是App中全局的窗口管理模塊,因此是個(gè)Singleton脱柱。其中管理著該App中的ViewRootImpl伐弹,DecorView等結(jié)構(gòu)。

WMS(WindowManagerService)

窗口的管理者榨为。與AMS不同惨好,一些高層的App中的概念,如進(jìn)程等随闺,WMS是不care的日川。因?yàn)閃MS只對(duì)窗口進(jìn)行管理,哪個(gè)進(jìn)程的它不關(guān)心矩乐。像Activity這些概念在WMS仍然有龄句,因?yàn)锳ctivity對(duì)窗口的管理會(huì)產(chǎn)生影響回论。

WMS主要責(zé)任是維護(hù)窗口堆棧,計(jì)算每個(gè)窗口的layer信息交給SF分歇,替App申請(qǐng)和調(diào)整繪圖Surface傀蓉,當(dāng)窗口顯示狀態(tài)變化了還要通知其它模塊,另外還要處理系統(tǒng)輸入职抡。所以說葬燎,WMS可能是與其它模塊交互最多的模塊之一了。它與AMS繁调,App萨蚕,SF及Input等模塊都交集。Android中大體有以下幾種窗口類型:1.應(yīng)用窗口蹄胰,一般來說就是Activity的主窗口岳遥。但也有些情況App沒有Activity,直接把自定義的View添加到WMS中裕寨,比如浮動(dòng)窗口浩蓉。2.子窗口,需要有一個(gè)父窗口宾袜,如Context Menu捻艳,Option Menu,Popup Window和Dialog等庆猫。3.系統(tǒng)窗口认轨,如狀態(tài)欄,鎖屏窗口月培,輸入法窗口嘁字,壁紙窗口和Toast之流,由系統(tǒng)創(chuàng)建的杉畜,不依賴于父窗口纪蜒。

Window:每個(gè)App雖然都可以做得各不相同,但是作為有大量用戶交互的系統(tǒng)此叠,窗口之間必須要有統(tǒng)一的交互模式纯续,這樣才能減小用戶的學(xué)習(xí)成本。這些共性比如title, action bar的顯示和通用按鍵的處理等等灭袁。Window類就抽象了這些共性猬错。另外,它定義了一組Callback茸歧,Activity通過實(shí)現(xiàn)這些Callback被調(diào)用來處理事件兔魂。注意要和在WMS中的窗口區(qū)分開來,WMS中的窗口更像是App端的View举娩。

PhoneWindow:PhoneWindow是Window類的唯一實(shí)現(xiàn),至少目前是。這樣的設(shè)計(jì)下如果要加其它平臺(tái)的Window類型更加方便铜涉。每個(gè)Activity會(huì)有一個(gè)PhoneWindow智玻,在attach到ActivityThread時(shí)創(chuàng)建,保存在mWindow成員中芙代。

Context:運(yùn)行上下文吊奢,Activity和Service本質(zhì)上都是一個(gè)Context,Context包含了它們作為運(yùn)行實(shí)體的共性纹烹,如啟動(dòng)Activity页滚,綁定Service,處理Broadcast和Receiver等等铺呵。注意Application也會(huì)有Context裹驰。Activity的Context是對(duì)應(yīng)Activity的,Activity被殺掉(比如轉(zhuǎn)屏后)后就變了片挂。所以要注意如果有生命周期很長的對(duì)象有對(duì)Activity的Context的引用的話幻林,轉(zhuǎn)屏、返回這種會(huì)引起Activity銷毀的操作都會(huì)引起內(nèi)存泄露音念。而Application的Context生命周期是和App進(jìn)程一致的沪饺。關(guān)于Context的類結(jié)構(gòu)圖有下面的形式。Context是抽象類闷愤,定義了接口整葡。ContextImpl是Context的實(shí)現(xiàn)類,包含了實(shí)現(xiàn)讥脐。而ContextWrapper是Context的包裝類遭居,它把請(qǐng)求delegate給其中的ContextImpl類去完成。ContextThemeWrapper是ContextWrapper的裝飾類攘烛,它在ContextWrapper的基礎(chǔ)上提供了自定義的主題魏滚。這結(jié)構(gòu)初看有點(diǎn)亂,但結(jié)合下面的Decorator模式(java的設(shè)計(jì)模式)就一目了然了坟漱。

Surface:這是在App端管理圖形緩沖區(qū)的類鼠次,其中最重要的是圖形緩沖區(qū)隊(duì)列。經(jīng)由WMS從SF中得到IGraphicBufferProducer接口對(duì)象BufferQueue后芋齿,Surface便可以從該隊(duì)列中queue和dequeue圖形緩沖區(qū)腥寇。SurfaceControl在WMS中封裝了Surface以及與SF的交互。Canvas和Surface從字面意思上很像觅捆,但前者其實(shí)更確切地說不是“畫布”赦役,而是“畫家”。Surface中的圖形緩沖區(qū)才是App的畫布栅炒。

1.3結(jié)構(gòu)流程分析

從結(jié)構(gòu)上分析掂摔,應(yīng)用啟動(dòng)大體可以分為3塊:

1.ams啟動(dòng)的調(diào)用(見圖一)

2.應(yīng)用本身生命周期的調(diào)用(見圖二)

3.Wms畫圖的調(diào)用(見圖三)

簡(jiǎn)單的ams第一部分調(diào)用關(guān)系概括為:

圖一

ActivityStackSupervisor

->startActivityMayWait

->startActivityLocked

->startActivityUncheckedLocked

->resumeTopActivitiesLocked

->resumeTopActivitiesLocked

->resumeTopActivityLocked(ActivityRecord prev)?

->resumeTopActivityLocked(ActivityRecordprev,Bundleoptions)

->startSpecificActivityLocked

->mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);

它是從ams的startActivityAsUser開始术羔,主要為應(yīng)用創(chuàng)建各種對(duì)象信息,方便調(diào)用乙漓,比如ActivityInfo,ActivityRecord,Stack,TaskRecord對(duì)象级历,檢查調(diào)用者權(quán)限,檢查intent的合法性叭披,為intent找到相應(yīng)的應(yīng)用寥殖,把原activity暫停放入后臺(tái)task列表中,并且把ApplicationToken加入到wms的task隊(duì)列里面涩蜘。通知wms創(chuàng)建白色的過渡window嚼贡,方法為mWindowManager.setAppStartingWindow。

第二部分應(yīng)用生命周期的調(diào)用同诫,主要從ActvityThread的handleLaunchActivity開始粤策。

新啟動(dòng)的Activity的創(chuàng)建初始化主要是在handleLaunchActivity()中完成的。handleLaunchActivity()的作用是加載指定的Activity并運(yùn)行剩辟。這其中在App端主要是創(chuàng)建ActivityThread掐场,Activity,PhoneWindow贩猎,DecorView等對(duì)象熊户,并調(diào)用Activity生命周期中的onCreate(),onResume()函數(shù)執(zhí)行用戶邏輯吭服。正常點(diǎn)的App里onCreate里會(huì)調(diào)用setContentView設(shè)置主視圖嚷堡。setContentView()里主要是調(diào)用了installDecor(),其中會(huì)設(shè)置窗口的通用元素艇棕,如title, action bar之類蝌戒,還會(huì)把xml文件inflate成布局對(duì)象。

簡(jiǎn)單的調(diào)用關(guān)系概括為:

handleLaunchActivity

->performLaunchActivity

?->mInstrumentation.newActivity

-> activity.attach

->mInstrumentation.callActivityOnCreate?

?->activity.onCreate

-> activity.performStart()

->handleResumeActivity

->wm.addView(decor, l);

圖二

可以看到這時(shí)創(chuàng)建了DecorView沼琉,這便是Activity的主窗口的頂層視圖北苟。DecorView創(chuàng)建好后,handleResumeActivity()中會(huì)將它添加到WMS中去打瘪。當(dāng)App向WMS添加窗口時(shí)友鼻,會(huì)調(diào)用WindowManagerImpl的addView()。注意WindowManagerImpl中的addView()函數(shù)和ViewGroup里的addView()函數(shù)完全不一樣闺骚,后者是將View加入到本地的View組織架構(gòu)中去彩扔,和WMS沒有關(guān)系。

第三部分主要從addView()的流程如下:

首先通過WindowManagerImpl的addView()會(huì)創(chuàng)建對(duì)應(yīng)的ViewRootImpl僻爽,然后ViewRootImpl申請(qǐng)WMS得到Session(如果是App第一個(gè)Activity會(huì)新建)虫碉,其接口為IWindowSession,然后ViewRootImpl通過addToDisplay()把自己的ViewRootImpl::W(實(shí)現(xiàn)了IWindow接口)注冊(cè)給WMS胸梆。addView()的工作主要包括創(chuàng)建ViewRootImpl敦捧,和遠(yuǎn)程WMS建立Session须板,并將當(dāng)前視圖注冊(cè)到WMS這幾步【ぢ眩可以看到App端通過WindowManagerGlobal調(diào)用addView()逼纸,調(diào)用鏈到WMS就變成addWindow(),概念發(fā)生了改變济蝉,這也印證上面提到的App端和WMS端的Window概念不一樣的說法。

圖三

2.Process流程

2.1進(jìn)程啟動(dòng)

進(jìn)程的啟動(dòng)的入口函數(shù)是AMS.startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags,String hostingType, ComponentName hostingName, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge)菠发。在前面的文章中知道王滤,當(dāng)啟動(dòng)Activity、Service滓鸠、getContentProvider時(shí)如果目標(biāo)進(jìn)程未啟動(dòng)雁乡,那么就需要調(diào)用startProcessLocked()來啟動(dòng)目標(biāo)進(jìn)程。所有線程啟動(dòng)都是通過這里啟動(dòng)糜俗,包括activity踱稍,Service、Provider悠抹、Broadcast珠月。

2.1.1?AMS.startProcessLocked()

final ProcessRecord startProcessLocked(){

......

? ? startProcessLocked(app, hostingType, hostingNameStr);

.......

}

private?final?void?startProcessLocked(ProcessRecord app,String hostingType, String hostingNameStr) {

? ? ?// Start the process. ?It will either succeed and return a result containing

? ? // the PID of the new process, or else throw a RuntimeException.

? ? ?Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",

? ? app.processName, uid, uid, gids, debugFlags, mountExternal,

? ? app.info.targetSdkVersion, app.info.seinfo,null);

}

1.調(diào)用Process.start("android.app.ActivityThread"來啟動(dòng)ActivityThread的線程,并在等待PROC_START_TIMEOUT時(shí)間后楔敌,查看線程時(shí)候啟動(dòng)超時(shí)啤挎。

2.start函數(shù)直接調(diào)用Process.startViaZygote()-->zygoteSendArgsAndGetResult(),進(jìn)程是從Zygote中孵化出來的卵凑。

3.Zygote是向socket服務(wù)端寫數(shù)據(jù)庆聘,把創(chuàng)建進(jìn)程的請(qǐng)求通過socket通訊方式來讓framework的進(jìn)程孵化類zygote創(chuàng)建新進(jìn)程。而數(shù)據(jù)就是argsForZygote——一個(gè)以字符串List形式的把Process.start()所有調(diào)用參數(shù)都包含在里面的變量勺卢。

socket服務(wù)端收到創(chuàng)建新進(jìn)程的請(qǐng)求伙判,ZygoteConnection.runOnce()接收到新進(jìn)程的參數(shù),然后調(diào)用Zygote.forkAndSpecialize()來fork一個(gè)子進(jìn)程黑忱,在子進(jìn)程中會(huì)接著關(guān)閉socket宴抚,調(diào)用ZygoteInit.invokeStaticMain(cloader, className, mainArgs),即調(diào)用ActivityThread.main()杨何。新的應(yīng)用進(jìn)程會(huì)從ActivityThread的main()函數(shù)處開始執(zhí)行酱塔。

2.1.2?ActivityThread.main()

startProcessLocked方法后面就調(diào)用了ActivityThread.main,啟動(dòng)ActivityThread.attach()危虱。

public?static?void?main(String[] args) {

? ? ?Process.setArgV0("");

? ? ? Looper.prepareMainLooper();

? ? ?ActivityThread thread =newActivityThread();

? ? ?thread.attach(false);

}


private?void?attach(booleansystem) {

? ? sCurrentActivityThread=this;

? ? mSystemThread= system;

? ?if(!system) {

? ? ?RuntimeInit.setApplicationObject(mAppThread.asBinder());

? ? ? IActivityManager mgr = ActivityManagerNative.getDefault();

? ? ? mgr.attachApplication(mAppThread);

? ?}else{

? ......

}

2.1.3?AMS.attachApplicationLocked()

attachApplicationLocked()函數(shù)主要做一些新進(jìn)程起來后的工作羊娃,比如設(shè)置ProcessRecord信息、獲取ContentProvider信息返回給ActivityThread埃跷、啟動(dòng)該進(jìn)程的Activity蕊玷、Service邮利、BroadCast等工作(四大組件相關(guān)),下面是詳細(xì)分析垃帅。

1.在調(diào)用startProcessLocked()啟動(dòng)進(jìn)程時(shí)延届,便將ProcessRecord和Pid加入mPidsSelfLocked中,故此時(shí)app不為null贸诚。

2.啟動(dòng)應(yīng)用所包含的ContentProvider方庭,相當(dāng)于將ContentProvider注冊(cè)到AMS中來,然后再把返回的參數(shù)providers傳給ActivityThread酱固,ActivityThread根據(jù)參數(shù)加載對(duì)應(yīng)的ContentProvider到應(yīng)用進(jìn)程中來械念,應(yīng)用進(jìn)程加載ContentProvider完成后會(huì)調(diào)用AMS.publishContentProviders()將ContentProvider信息公開。(如果應(yīng)用包含有provider的信息运悲,被oom強(qiáng)制殺死時(shí)會(huì)自動(dòng)重啟線程)

3.保證應(yīng)用的dex龄减,只有在特殊的運(yùn)行“沒有預(yù)先dexopt”模式才有作用。

4.AMS側(cè)對(duì)該進(jìn)程進(jìn)行一些初始化操作后邊將一些必要信息傳給ActivityThread班眯,這個(gè)步驟對(duì)應(yīng)用非常重要希停,應(yīng)用很多初始化的數(shù)據(jù)都在這里生成,包括初始化時(shí)區(qū)署隘,設(shè)置資源宠能,density,dpi定踱,cache目錄信息棍潘,虛擬器大小等。

5.進(jìn)程起來后崖媚,調(diào)用ActivityStackSupervisor.attachApplicationLocked來啟動(dòng)相應(yīng)Activity亦歉。如果未啟動(dòng)的Activity要跑在當(dāng)前啟動(dòng)的進(jìn)程中,那么直接調(diào)用realStartActivityLocked()來啟動(dòng)當(dāng)前畅哑,realStartActivityLocked就是啟動(dòng)Activity的真正函數(shù)肴楷。

6.進(jìn)程起來后調(diào)用ActiveServices.attachApplicationLocked()啟動(dòng)相應(yīng)服務(wù),尋找要在當(dāng)前進(jìn)程中啟動(dòng)的Activity荠呐,并啟動(dòng)之赛蔫。mPendingServices中保存著等待該進(jìn)程啟動(dòng)的Service,現(xiàn)在進(jìn)程已經(jīng)啟動(dòng)了泥张,所以mPendingServices中保存的服務(wù)也可以啟動(dòng)了呵恢,即在下面調(diào)用realStartServiceLocked()來啟動(dòng)服務(wù)。

7.處理廣播媚创,將原本要發(fā)到當(dāng)前進(jìn)程的廣播處理掉渗钉,調(diào)用isPendingBroadcastProcessLocked()來判斷當(dāng)前啟動(dòng)的進(jìn)程是否是PendingBroadcast等待的進(jìn)程,如果是就把PendingBroadcast廣播發(fā)送給當(dāng)前這個(gè)進(jìn)程中去。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鳄橘,一起剝皮案震驚了整個(gè)濱河市声离,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘫怜,老刑警劉巖术徊,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鲸湃,居然都是意外死亡赠涮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門暗挑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來世囊,“玉大人,你說我怎么就攤上這事窿祥。” “怎么了蝙寨?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵晒衩,是天一觀的道長。 經(jīng)常有香客問我墙歪,道長听系,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任虹菲,我火速辦了婚禮靠胜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘毕源。我一直安慰自己浪漠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布霎褐。 她就那樣靜靜地躺著址愿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冻璃。 梳的紋絲不亂的頭發(fā)上响谓,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音省艳,去河邊找鬼娘纷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛跋炕,可吹牛的內(nèi)容都是我干的赖晶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼枣购,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嬉探!你這毒婦竟也來了擦耀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤涩堤,失蹤者是張志新(化名)和其女友劉穎眷蜓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胎围,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吁系,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了白魂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汽纤。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖福荸,靈堂內(nèi)的尸體忽然破棺而出蕴坪,到底是詐尸還是另有隱情,我是刑警寧澤敬锐,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布背传,位于F島的核電站,受9級(jí)特大地震影響台夺,放射性物質(zhì)發(fā)生泄漏径玖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一颤介、第九天 我趴在偏房一處隱蔽的房頂上張望梳星。 院中可真熱鬧,春花似錦滚朵、人聲如沸冤灾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞳购。三九已至,卻和暖如春亏推,著一層夾襖步出監(jiān)牢的瞬間学赛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國打工吞杭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盏浇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓芽狗,卻偏偏與公主長得像绢掰,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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