Android 07--View的繪制機(jī)制簡介

????從開發(fā)人員角度,我們可以知道秸讹,整個App主要有各個活動、服務(wù)等相關(guān)組成雅倒,而用戶交互的基礎(chǔ)來自于界面瑟枫。存在用戶交互就離不開界面,界面又依賴于各個View和ViewGroup所組成夫椭,也因此盛垦,對于View的繪制流程,對于我們自定義View也好裁良,活動界面的創(chuàng)建流程等都是十分重要的知識凿将。在這里我們將其簡單的梳理一遍。本節(jié)的章節(jié)目錄如下:

1价脾、視圖結(jié)構(gòu)(又稱:android視圖構(gòu)成

2牧抵、View繪制主要流

3View繪制流程之大小測量——Measure

4侨把、View繪制流程之布局(位置)測量——Layout

5犀变、View繪制流程之內(nèi)容繪制——Draw

6View提供的API控制視圖的部分常用方法

? ? 從上述的步驟秋柄,我們逐步講解一下获枝,構(gòu)建一個大致的知識網(wǎng)絡(luò)。

1骇笔、視圖結(jié)構(gòu)(又稱:android視圖構(gòu)成

Activity窗口簡要示意圖

? ? 從上圖來看省店,我們可以看到一個比較清晰的構(gòu)成,我們來對上圖做出簡單解釋:

????DecorView是一個應(yīng)用窗口的根容器笨触,它本質(zhì)上是一個FrameLayout萨西。DecorView有唯一一個子View,它是一個垂直LinearLayout旭旭,包含兩個子元素谎脯,一個是TitleView(ActionBar的容器),另一個是ContentView(窗口內(nèi)容的容器)持寄。關(guān)于ContentView源梭,它是一個FrameLayout(android.R.id.content),我們平常用的setContentView就是設(shè)置它的子View稍味。上圖還表達(dá)了每個Activity都與一個Window(具體來說是PhoneWindow)相關(guān)聯(lián)废麻,用戶界面則由Window所承載。

在這里我們先講解一下涉及到的部分比較陌生卻又重要的角色(如覺繁瑣模庐,可自行跳過):

? ??Window:窗口的概念上來看是一個比較宏大的思想烛愧,指代屏幕上用于繪制各種UI元素及響應(yīng)用戶輸入事件的一個矩形區(qū)域。通常具備以下兩個特點(diǎn):

? ? 1、獨(dú)立繪制怜姿,不與其它界面相互影響慎冤;

? ? 2、不會觸發(fā)其它界面的輸入事件沧卢;

????在Android系統(tǒng)中蚁堤,窗口是獨(dú)占一個Surface實(shí)例的顯示區(qū)域,每個窗口的Surface由WindowManagerService分配但狭。我們可以把Surface看作一塊畫布披诗,應(yīng)用可以通過Canvas或OpenGL在其上面作畫。畫好之后立磁,通過SurfaceFlinger將多塊Surface按照特定的順序(即Z-order/Z 軸)進(jìn)行混合呈队,而后輸出到FrameBuffer中,這樣用戶界面就得以顯示唱歧。

? ? 其中宪摧,窗口在Android Framework中的實(shí)現(xiàn)為android.view.Window這個抽象類,這個抽象類是對Android系統(tǒng)中的窗口的抽象迈喉。它有三個核心組件構(gòu)成:

? ? 1、WindowManager.LayoutParams:窗口的布局參數(shù)温圆;

? ? 2挨摸、Callback: 窗口的回調(diào)接口,通常由Activity實(shí)現(xiàn)岁歉;

? ? 3得运、ViewTree: 窗口所承載的控件樹。


? ??PhoneWindow:類android.view.Window的一個實(shí)現(xiàn)類锅移,也是其唯一實(shí)現(xiàn)類熔掺。

????我們平時調(diào)用setContentView()方法設(shè)置Activity的用戶界面時,實(shí)際上就完成了對所關(guān)聯(lián)的PhoneWindow的ViewTree的設(shè)置非剃。我們還可以通過Activity類的requestWindowFeature()方法來定制Activity關(guān)聯(lián)PhoneWindow的外觀置逻,這個方法實(shí)際上做的是把我們所請求的窗口外觀特性存儲到了PhoneWindow的mFeatures成員中,在窗口繪制階段生成外觀模板時备绽,會根據(jù)mFeatures的值繪制特定外觀券坞。

????內(nèi)部包含了一個DecorView對象,該DectorView對象是所有應(yīng)用窗口(Activity界面)的根View肺素。 簡而言之恨锚,PhoneWindow類是把一個FrameLayout類即DecorView對象進(jìn)行一定的包裝,將它作為應(yīng)用窗口的根View倍靡,并提供一組通用的窗口操作接口猴伶。


? ??DecorView:是PhoneWindow類的內(nèi)部類(后面版本將DecorView拿出來了)。該類是一個FrameLayout的子類,并且是PhoneWindow的子類他挎,該類就是對普通的FrameLayout進(jìn)行功能的擴(kuò)展筝尾,更確切點(diǎn)可以說是修飾(Decor的英文全稱是Decoration,即“修飾”的意思)雇盖,比如說添加TitleBar(標(biāo)題欄)忿等,以及TitleBar上的滾動條等 。最重要的一點(diǎn)是崔挖,它是所有應(yīng)用窗口的根View 贸街。它主要有以下功能:

? ? 1、Dispatch ViewRoot分發(fā)來的key狸相、touch薛匪、trackball等外部事件;

? ? 2脓鹃、DecorView有一個直接的子View逸尖,我們稱之為System Layout,這個View是從系統(tǒng)的Layout.xml中解析出的,它包含當(dāng)前UI的風(fēng)格瘸右,如是否帶title娇跟、是否帶ActionBar等√可以稱這些屬性為Window decorations苞俘。

? ? 3、作為PhoneWindow與ViewRoot之間的橋梁龄章,ViewRoot通過DecorView設(shè)置窗口屬性吃谣。可以這樣獲取 View:view =getWindow().getDecorView();

?DecorView只有一個子元素為LinearLayout做裙。代表整個Window界面岗憋,包含通知欄,標(biāo)題欄锚贱,內(nèi)容顯示欄三塊區(qū)域仔戈。DecorView里面TitleView:標(biāo)題,可以設(shè)置requestWindowFeature(Window.FEATURE_NO_TITLE)取消掉,ContentView:是一個id為content的FrameLayout拧廊。我們平常在Activity使用的setContentView就是設(shè)置在這里杂穷,也就是在FrameLayout上;


? ??ViewRoot:在介紹View的繪制前卦绣,首先我們需要知道是誰負(fù)責(zé)執(zhí)行View繪制的整個流程耐量。實(shí)際上,View的繪制是由ViewRoot來負(fù)責(zé)的滤港。每個應(yīng)用程序窗口的decorView都有一個與之關(guān)聯(lián)的ViewRoot對象廊蜒,這種關(guān)聯(lián)關(guān)系是由WindowManager來維護(hù)的趴拧。(又一說DecorView是ViewRoot與WindowManager的關(guān)聯(lián)紐帶,總之這三者是依據(jù)彼此進(jìn)行相互聯(lián)系山叮,所以這兩種說法應(yīng)該不沖突)著榴。

????那么decorView與ViewRoot的關(guān)聯(lián)關(guān)系是在什么時候建立的呢?答案是Activity啟動時屁倔,ActivityThread.handleResumeActivity()方法中建立了它們兩者的關(guān)聯(lián)關(guān)系脑又。這里我們不具體分析它們建立關(guān)聯(lián)的時機(jī)與方式,感興趣的同學(xué)可以參考相關(guān)源碼锐借。

? ? 在這里问麸,我們就可以知道我們通常的setContentView,其實(shí)就是將我們對應(yīng)的xml布局界面制定添加到DecorView的子元素ContentView里面而已钞翔。當(dāng)然严卖,我們也借此需要明確的一點(diǎn)就是,setContentView并不是繪制流程的開始(雖然他是我們主要界面的指定)布轿,setContentView()方法所處的時間點(diǎn)哮笆,Activity只是完成了ContentView的創(chuàng)建,還未開始繪制汰扭。那View繪制的起點(diǎn)是在什么時候呢稠肘?

????當(dāng)建立好了decorView與ViewRoot的關(guān)聯(lián)后,ViewRoot類的requestLayout()方法會被調(diào)用萝毛,以完成應(yīng)用程序用戶界面的初次布局项阴。該方法中調(diào)用了scheduleTraversals()方法來調(diào)度一次完成的繪制流程,該方法會向主線程發(fā)送一個“遍歷”消息珊泳,最終會導(dǎo)致ViewRootImpl的performTraversals()方法被調(diào)用鲁冯。從這里開始拷沸,系統(tǒng)就開始了View的繪制流程了色查!

2View繪制主要流

????View繪制大致可以分為三個流程撞芍,分別是measure(測量)秧了,layout(布局),draw(繪制),這三者的順序就是measure(測量)->layout(布局)->draw(繪制)序无。

????measure: 判斷是否需要重新計(jì)算View的大醒檎薄(寬高),需要的話則計(jì)算帝嗡;

????layout: 判斷是否需要重新計(jì)算View的位置晶通,需要的話則計(jì)算;

????draw: 判斷是否需要重新繪制View哟玷,需要的話則重繪制狮辽。

View的簡要繪制流程圖

? ? 當(dāng)然上圖是高度抽象化的簡要流程一也,對于我們陌生的時候,作為熟悉的借鑒是十分友好的喉脖,而且也十分符合我們的章節(jié)流程椰苟。不過對于開發(fā)人員來說,我們常常遇見View里面的各種各樣的方法树叽,其中對應(yīng)方法對應(yīng)的時機(jī)更需要我們?nèi)チ私庥吆拍芨玫剡\(yùn)用,因此我把大致的方法流程圖也貼出來:

View繪制具體方法流程圖

? ? 在這里補(bǔ)充一下题诵,樹的遍歷是有序的洁仗,由父視圖到子視圖,每一個ViewGroup 負(fù)責(zé)測繪它所有的子視圖仇轻,而最底層的 View 會負(fù)責(zé)測繪自身京痢。所以,無論是Measure或者Layout都是自上而下地進(jìn)行遍歷篷店。

3祭椰、View繪制流程之大小測量——Measure

? ? 我們也知道屏幕和其他相關(guān)因素的限制,View的大小寬高不能隨心所欲疲陕,也因此我們需要進(jìn)行測量方淤,前頭也說明了,Measure的目的就是為了測量View的寬高蹄殃。對于開發(fā)人員携茂,我們最基礎(chǔ)與常見的布局寬高設(shè)置,有以下幾種值選定:

? ? 1诅岩、具體值:以px或者dp為單位

? ? 2讳苦、fill _ parent:這個已經(jīng)過時,強(qiáng)制性使子視圖的大小擴(kuò)展至與父視圖大小相等(不含padding )

? ? 3吩谦、match _ parent:特性和fill_parent相似鸳谜,Android版本大于2.3使用

? ? 4、wrap _ content:自適應(yīng)大小式廷,強(qiáng)制性地使視圖擴(kuò)展以便顯示其全部內(nèi)容(含padding )

? ? 接下來咐扭,我們就要著重講一下測量模式了,就如上文所述滑废,Measure是自上而下的蝗肪,而且父布局也可能對其進(jìn)行限制,這種時候就通過測量模式進(jìn)行傳遞約束了蠕趁。而測量模式與測量大小薛闪,統(tǒng)一組成測量規(guī)格:

??MeasureSpec:MeasureSpec(View的內(nèi)部類)測量規(guī)格為int型,值由高2位規(guī)格模式specMode和低30位具體尺寸specSize組成俺陋。其中SpecMode只有三種值:

????MeasureSpec.EXACTLY? ? //確定模式豁延,父View希望子View的大小是確定的怀各,由specSize決定;

????MeasureSpec.AT_MOST? ?//最多模式术浪,父View希望子View的大小最多是specSize指定的值瓢对;

????MeasureSpec.UNSPECIFIED? ? //未指定模式,父View完全依據(jù)子View的設(shè)計(jì)值來決定胰苏;

?注意對于一個ViewGroup或者View的寬高而言硕蛹,都一一對應(yīng)一個MeasureSpec。

????當(dāng)然硕并,通過“父親(View)”的測量模式與測量寬高法焰,結(jié)合本身(子View)的LayoutParams可以進(jìn)行本身(子View)的測量寬高,其中主要存在于9種情況(我將9中情況單獨(dú)列出來倔毙,再將結(jié)果列出來埃仪,有興趣的可以自己推導(dǎo)一下):

9種情況條件圖
9種情況結(jié)果圖

通過上述介紹,我們大致知道測量規(guī)格里的測量大小于測量模式的影響與作用了陕赃,讓我們繼續(xù)看看測量的流程與對應(yīng)的作用卵蛉。首先是View的測量過程:

View的測量流程圖

? ? 我們簡單介紹一下上述的幾個方法的作用

? ? 1、measure()基本測量邏輯的判斷么库,為 final 類型傻丝,不可被復(fù)寫。但 measure 調(diào)用鏈最終會回調(diào) View/ViewGroup 對象的?onMeasure()方法诉儒,因此自定義視圖時葡缰,只需要復(fù)寫?onMeasure()?方法即可;

? ? 2忱反、onMeasure()該方法就是我們自定義視圖中實(shí)現(xiàn)測量邏輯的方法泛释,該方法的參數(shù)是父視圖對子視圖的 width 和 height 的測量要求。在我們自身的自定義視圖中温算,要做的就是根據(jù)該widthMeasureSpec 和heightMeasureSpec 計(jì)算視圖的 width 和 height怜校,不同的模式處理方式不同。

? ? 3米者、setMeasuredDimension()存儲測量后的寬和高韭畸。在?onMeasure(int widthMeasureSpec,

int heightMeasureSpec)?方法中調(diào)用宇智,將計(jì)算得到的尺寸蔓搞,傳遞給該方法,測量階段即結(jié)束随橘。該方法也是必須要調(diào)用的方法喂分,否則會報(bào)異常。在我們在自定義視圖的時候机蔗,不需要關(guān)心系統(tǒng)復(fù)雜的Measure 過程的蒲祈,只需調(diào)用setMeasuredDimension()設(shè)置根據(jù) MeasureSpec 計(jì)算得到的尺寸即可甘萧,你可以參考?ViewPagerIndicator?的 onMeasure 方法。

? ? 4梆掸、getDefaultSize()根據(jù)View寬/高的測量規(guī)格計(jì)算View的寬/高扬卷。

在自定義View時,我們常常會利用以下兩個方法:

????getDefaultSize() = 計(jì)算View的寬/高值酸钦;

????setMeasuredDimension() = 存儲測量后的View寬 / 高怪得,注意:如上文所說,此方法必須在onMeasure()方法中調(diào)用卑硫,否則會發(fā)生異常徒恋。

? ? 這里我們再補(bǔ)充一下,再OnMeasure與OnMeasureDimension方法之間欢伏,就是在測量的過程種入挣,如果是ViewGroup又將多處對子View的遍歷與合并:

ViewGroup測量流程圖

????1、measure():基本測量邏輯的判斷硝拧。

? ? 2径筏、onMeasure():遍歷所有的子View進(jìn)行測量,如何遍歷子View進(jìn)行測量呢障陶,就是調(diào)用measureChildren()方法匠璧,當(dāng)所有的子View測量完成后,將會合并所有子View的尺寸最終計(jì)算出ViewGroup的尺寸咸这。

? ? 3夷恍、measureChildren():遍歷子View并對子View進(jìn)行測量,后續(xù)會調(diào)用measureChild()方法媳维。

? ? 4酿雪、measureChild():計(jì)算出單個子View的MeasureSpec,通過調(diào)用getChildMeasureSpce()方法實(shí)現(xiàn)侄刽,調(diào)用每個子View的measure()方法進(jìn)行測量指黎。

? ? 5、getChildMeasureSpec():計(jì)算出子View的MeasureSpec州丹。

? ? 6醋安、setMeasuredDimension():存儲測量后的寬和高。

4墓毒、View繪制流程之布局(位置)測量——Layout

????Layout的目的就是確認(rèn)View&ViewGroup的位置吓揪。也就是計(jì)算View&ViewGroup的四個頂點(diǎn)的位置,left,top,right,bottom所计。同樣柠辞,我們先看看View的測量過程:

View的布局測量流程

?layout()調(diào)用layout()方法主要為了計(jì)算View自身的位置,在此方法調(diào)用路徑中有一個方法特別重要主胧,這個方法就是setFrame()叭首,它的作用就是根據(jù)傳入的4個位置值习勤,設(shè)置View本身的四個頂點(diǎn)位置,也就是用來確定最終View的位置的焙格。接下來就是回調(diào)onLayout()方法图毕。

?onLayout()對于View的onLayout()方法來說,它是一個空實(shí)現(xiàn)眷唉。為什么View的onLayout()方法是空實(shí)現(xiàn)呢吴旋?因?yàn)閛nLayout()方法作用是計(jì)算此VIew的子View的位置,對于單一的View而言厢破,它并不存在子View荣瑟,因此它肯定是空實(shí)現(xiàn)啦!

? ? 我們再看看ViewGroup的布局測量過程:

ViewGroup的布局測量流程

layout()

調(diào)用layout()方法計(jì)算ViewGroup自身的位置摩泪,在此方法調(diào)用路徑中有一個方法特別重要笆焰,這個方法就是setFrame(),它的作用就是根據(jù)傳入的4個位置值见坑,設(shè)置View本身的四個頂點(diǎn)位置嚷掠,也就是用來確定最終View的位置的。接下來就是回調(diào)onLayout()方法荞驴。

??onLayout()對于ViewGroup而言不皆,它不僅僅要確認(rèn)自身的位置,它還要計(jì)算它的子View的位置熊楼,因此onLayout的作用就是遍歷并計(jì)算每個子View的位置霹娄。

5View繪制流程之內(nèi)容繪制——Draw

????Draw過程的目的繪制View&ViewGroup的視圖鲫骗。我們先看看View的繪制過程:

View的繪制流程圖

? ? 1犬耻、draw():繪制View自身。

? ? 2执泰、drawBackground():繪制View自身的背景枕磁。

? ? 3、onDraw():繪制View自身的內(nèi)容术吝。

? ? 4计济、dispatchDraw():對于View而言,它是空實(shí)現(xiàn)排苍,因?yàn)樗淖饔檬抢L制子View的沦寂,因?yàn)閱我坏腣iew沒有子View,因此它是空實(shí)現(xiàn)纪岁。

? ? 5凑队、onDrawScrollBars():它是繪制滑動條等裝飾的则果,比如ListView的滑動條幔翰。

ViewGroup的繪制流程:

ViewGroup的繪制流程圖

? ? 1漩氨、draw():繪制ViewGroup自身。

? ? 2遗增、drawBackground():繪制ViewGroup自身的背景叫惊。

? ? 3、onDraw():繪制View自身的內(nèi)容做修。

? ? 4霍狰、dispatchDraw():對于ViewGroup而言,它是存在子View的饰及,因此此方法就是用來遍歷子View蔗坯,然后讓每個子View進(jìn)入Draw過程從而完成繪制過程。

? ? 5燎含、onDrawScrollBars():ViewGroup的裝飾繪制宾濒。

6View提供的API控制視圖的部分常用方法

????invalidate和postInvalidate方法:都是請求重新繪制視圖屏箍,調(diào)用draw绘梦,區(qū)別在于:

? ? 1、invalidate在主線程調(diào)用

? ? 2赴魁、postInvalidate是在非主線程調(diào)用

????requestLayout方法:requestLayout()方法會調(diào)用measure過程和layout過程卸奉,不會調(diào)用draw過程,也不會重新繪制任何View包括該調(diào)用者本身颖御。

? ? 到這里榄棵,我們就簡單地將View的繪制機(jī)制/流程捋了一遍,當(dāng)然還是不夠全面潘拱,甚至存在偏頗或者錯誤的地方秉继,如果您看到了發(fā)現(xiàn)了,真誠地希望您能直接指正泽铛,本人將不勝感激尚辑!上述圖文主要來自與參考博客和參考書籍,本人根據(jù)自己的理解進(jìn)行部分拼接與闡述盔腔,未與對應(yīng)作者進(jìn)行溝通杠茬,如其有合理要求可與本人聯(lián)系,本人將及時改正弛随。

---------------------

參考書籍:《Android開發(fā)藝術(shù)探索》

參考博文:

---------------------

作者:ClAndEllen? 來源:CSDN? ?題目:Android知識體系總結(jié)之Android部分View繪制機(jī)制篇

鏈接:https://blog.csdn.net/ClAndEllen/article/details/79365250

---------------------

作者:absfree? 來源:簡書? ?題目:深入理解Android之View的繪制流程

鏈接:http://www.reibang.com/p/060b5f68da79

---------------------

作者:lightSky? 來源:CodeKK? ?題目:公共技術(shù)點(diǎn)之 View 繪制流程

鏈接:http://www.codekk.com/blogs/detail/54cfab086c4761e5001b253f

---------------------

作者:jackzhouyu??來源:簡書? ?題目:Android組件View繪制流程原理分析

鏈接:http://www.codekk.com/blogs/detail/54cfab086c4761e5001b253f

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瓢喉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舀透,更是在濱河造成了極大的恐慌栓票,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異走贪,居然都是意外死亡佛猛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門坠狡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來继找,“玉大人,你說我怎么就攤上這事逃沿∮ざ桑” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵凯亮,是天一觀的道長边臼。 經(jīng)常有香客問我,道長假消,這世上最難降的妖魔是什么硼瓣? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮置谦,結(jié)果婚禮上堂鲤,老公的妹妹穿的比我還像新娘。我一直安慰自己媒峡,他們只是感情好瘟栖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谅阿,像睡著了一般半哟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上签餐,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天察净,我揣著相機(jī)與錄音衣盾,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛们拙,可吹牛的內(nèi)容都是我干的腐泻。 我是一名探鬼主播桐经,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拓哟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了河泳?” 一聲冷哼從身側(cè)響起沃呢,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拆挥,沒想到半個月后薄霜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年惰瓜,在試婚紗的時候發(fā)現(xiàn)自己被綠了否副。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸵熟,死狀恐怖副编,靈堂內(nèi)的尸體忽然破棺而出负甸,到底是詐尸還是另有隱情流强,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布呻待,位于F島的核電站打月,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蚕捉。R本人自食惡果不足惜奏篙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望迫淹。 院中可真熱鬧秘通,春花似錦、人聲如沸敛熬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽应民。三九已至话原,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诲锹,已是汗流浹背繁仁。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留归园,地道東北人黄虱。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像庸诱,于是被迫代替她去往敵國和親悬钳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355