MS(3):Android之機制原理篇

五翩剪、重點機制原理

1坡慌、Handler機制

MS思考:Android面試一天一題(8 Day):Handler相關

分析篇:Android 異步消息處理機制源碼解析

問題:handler機制介紹

1.MessageQueue:讀取會自動刪除消息溢吻,單鏈表維護川梅,在插入和刪除上有優(yōu)勢歼狼。在其next()中會無限循環(huán)诀蓉,不斷判斷是否有消息萍嬉,有就返回這條消息并移除耐床。

2.Looper:Looper創(chuàng)建的時候會創(chuàng)建一個MessageQueue澜公,調用loop()方法的時候消息循環(huán)開始冕末,loop()也是一個死循環(huán)萍歉,會不斷調用messageQueue的next(),當有消息就處理档桃,否則阻塞在messageQueue的next()中枪孩。當Looper的quit()被調用的時候會調用messageQueue的quit(),此時next()會返回null,然后loop()方法也跟著退出胳蛮。

3.Handler:在主線程構造一個Handler销凑,然后在其他線程調用sendMessage(),此時主線程的MessageQueue中會插入一條message,然后被Looper使用仅炊。

4.系統(tǒng)的主線程在ActivityThread的main()為入口開啟主線程斗幼,其中定義了內部類Activity.H定義了一系列消息類型,包含四大組件的啟動停止抚垄。

Handler通過調用sendmessage方法把消息放在消息隊列MessageQueue中蜕窿,Looper負責把消息從消息隊列中取出來,重新再交給Handler進行處理呆馁,三者形成一個循環(huán)

通過構建一個消息隊列桐经,把所有的Message進行統(tǒng)一的管理,當Message不用了浙滤,并不作為垃圾回收阴挣,而是放入消息隊列中,供下次handler創(chuàng)建消息時候使用纺腊,提高了消息對象的復用畔咧,減少系統(tǒng)垃圾回收的次數(shù)

每一個線程茎芭,都會單獨對應的一個looper,這個looper通過ThreadLocal來創(chuàng)建誓沸,保證每個線程只創(chuàng)建一個looper梅桩,looper初始化后就會調用looper.loop創(chuàng)建一個MessageQueue,這個方法在UI線程初始化的時候就會完成拜隧,我們不需要手動創(chuàng)建

問題:Android為什么只能在主進程中更新UI宿百?主線程有Looper的死循環(huán)為什么不會卡死。

關于Android中為什么主線程不會因為Looper.loop()里的死循環(huán)卡死洪添?引發(fā)的思考垦页,事實可能不是一個 epoll 那么 簡單。

2干奢、HandlerThread理解

3外臂、View事件分發(fā)機制及整個流程

分析篇:Android View事件分發(fā)機制源碼分析

問題:介紹觸摸事件的分發(fā)機制

(1) 事件從Activity.dispatchTouchEvent()開始傳遞,只要沒有被停止或攔截律胀,從最上層的View(ViewGroup)開始一直往下(子View)傳遞。子View可以通過onTouchEvent()對事件進行處理貌矿。

(2) 事件由父View(ViewGroup)傳遞給子View炭菌,ViewGroup可以通過onInterceptTouchEvent()對事件做攔截,停止其往下傳遞逛漫。

(3) 如果事件從上往下傳遞過程中一直沒有被停止黑低,且最底層子View沒有消費事件,事件會反向往上傳遞酌毡,這時父View(ViewGroup)可以進行消費克握,如果還是沒有被消費的話,最后會到Activity的onTouchEvent()函數(shù)枷踏。

(4) 如果View沒有對ACTION_DOWN進行消費菩暗,之后的其他事件不會傳遞過來。

(5) OnTouchListener優(yōu)先于onTouchEvent()對事件進行消費旭蠕。

上面的消費即表示相應函數(shù)返回值為true停团。

問題:View中 setOnTouchListener的onTouch,onTouchEvent掏熬,onClick的執(zhí)行順序

追溯到View的dispatchTouchEvent源碼查看佑稠,有這么一段代碼

public boolean dispatchTouchEvent(MotionEvent event) {

if (!onFilterTouchEventForSecurity(event)) {

return false;

}

if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&

mOnTouchListener.onTouch(this, event)) {

return true;

}

return onTouchEvent(event);

}

當以下三個條件任意一個不成立時,

mOnTouchListener不為null

view是enable的狀態(tài)

mOnTouchListener.onTouch(this, event)返回true旗芬,

函數(shù)會執(zhí)行到onTouchEvent舌胶。在這里我們可以看到,首先執(zhí)行的是mOnTouchListener.onTouch的方法疮丛,然后是onTouchEvent方法

繼續(xù)追溯源碼幔嫂,到onTouchEvent()觀察辆它,發(fā)現(xiàn)在處理ACTION_UP事件里有這么一段代碼

if (!post(mPerformClick)) {

performClick();

}

此時可知,onClick方法也在最后得到了執(zhí)行

所以三者的順序是:

setOnTouchListener() 的onTouch

onTouchEvent()

onClick()

4婉烟、View繪制機制和加載過程

Android組件View繪制流程原理分析

measure()方法娩井,layout(),draw()三個方法主要存放了一些標識符似袁,來判斷每個View是否需要再重新測量洞辣,布局或者繪制,主要的繪制過程還是在onMeasure昙衅,onLayout扬霜,onDraw這個三個方法中

1.onMesarue()為整個View樹計算實際的大小,即設置實際的高(對應屬性:mMeasuredHeight)和寬(對應屬性: mMeasureWidth)而涉,每個View的控件的實際寬高都是由父視圖和本身視圖決定的著瓶。

2.onLayout()為將整個根據(jù)子視圖的大小以及布局參數(shù)將View樹放到合適的位置上。

3. onDraw()開始繪制圖像啼县,繪制的流程如下

首先繪制該View的背景

調用onDraw()方法繪制視圖本身 (每個View都需要重載該方法材原,ViewGroup不需要實現(xiàn)該方法)

如果該View是ViewGroup,調用dispatchDraw ()方法繪制子視圖

繪制滾動條

5季眷、Binder機制

MS思考:Android面試一天一題(Day 35:神秘的Binder機制)

分析篇:Android Bander設計與實現(xiàn) - 設計篇

Binder機制原理和底層實現(xiàn)

1.在Activity和Service進行通訊的時候余蟹,用到了Binder。

1.當屬于同個進程我們可以繼承Binder然后在Activity中對Service進行操作

2.當不屬于同個進程子刮,那么要用到AIDL讓系統(tǒng)給我們創(chuàng)建一個Binder威酒,然后在Activity中對遠端的Service進行操作。

2.系統(tǒng)給我們生成的Binder:

1.Stub類中有:接口方法的id挺峡,有該Binder的標識葵孤,有asInterface(IBinder)(讓我們在Activity中獲取實現(xiàn)了Binder的接口,接口的實現(xiàn)在Service里橱赠,同進程時候返回Stub否則返回Proxy)尤仍,有onTransact()這個方法是在不同進程的時候讓Proxy在Activity進行遠端調用實現(xiàn)Activity操作Service

2.Proxy類是代理,在Activity端病线,其中有:IBinder mRemote(這就是遠端的Binder)吓著,兩個接口的實現(xiàn)方法不過是代理最終還是要在遠端的onTransact()中進行實際操作。

3.哪一端的Binder是副本送挑,該端就可以被另一端進行操作绑莺,因為Binder本體在定義的時候可以操作本端的東西。所以可以在Activity端傳入本端的Binder惕耕,讓Service端對其進行操作稱為Listener纺裁,可以用RemoteCallbackList這個容器來裝Listener,防止Listener因為經(jīng)歷過序列化而產(chǎn)生的問題。

4.當Activity端向遠端進行調用的時候欺缘,當前線程會掛起栋豫,當方法處理完畢才會喚醒。

5.如果一個AIDL就用一個Service太奢侈谚殊,所以可以使用Binder池的方式丧鸯,建立一個AIDL其中的方法是返回IBinder,然后根據(jù)方法中傳入的參數(shù)返回具體的AIDL嫩絮。

6.IPC的方式有:Bundle(在Intent啟動的時候傳入丛肢,不過是一次性的),文件共享(對于SharedPreference是特例剿干,因為其在內存中會有緩存)蜂怎,使用Messenger(其底層用的也是AIDL,同理要操作哪端置尔,就在哪端定義Messenger)杠步,AIDL,ContentProvider(在本進程中繼承實現(xiàn)一個ContentProvider榜轿,在增刪改查方法中調用本進程的SQLite幽歼,在其他進程中查詢),Socket

6谬盐、跨進程通信(AIDL及其它) --1

MS思考:Android面試一天一題(Day 36:AIDL)

分析篇:AIDL的使用情況和實例介紹

Android:學習AIDL试躏,這一篇文章就夠了(上)

Android:學習AIDL,這一篇文章就夠了(下)

你真的理解AIDL中的in设褐,out,inout么泣刹?

問題:Android 進程間的通信有哪幾種方式

Bundle/Intent傳遞數(shù)據(jù)助析,Messenger(消息隊列適合單線程,底層還是AIDL)椅您,AIDL外冀,ContentProvider,Socket

問題:Bundle掀泳、文件共享雪隧、ContentProvider、AIDL的使用場景

7员舵、異步任務機制之AsycTask

MS思考:Android面試一天一題(13 Day: AsyncTask)

分析篇:Android異步任務機制之AsycTask

問題:AsyncTask原理及不足

問題:AsynTask為什么要設計為只能夠一次任務?

最核心的還是線程安全問題脑沿,多個子線程同時運行,會產(chǎn)生狀態(tài)不一致的問題马僻。所以要務必保證只能夠執(zhí)行一次

問題:AsynTask造成的內存泄露的問題怎么解決庄拇,比如非靜態(tài)內部類AsynTask會隱式地持有外部類的引用,如果其生命周期大于外部activity的生命周期,就會出現(xiàn)內存泄漏

注意要復寫AsynTask的onCancel方法措近,把里面的socket溶弟,file等,該關掉的要及時關掉

在 Activity 的onDestory()方法中調用Asyntask.cancal方法

Asyntask內部使用弱引用的方式來持有Activity

問題:若Activity已經(jīng)銷毀瞭郑,此時AsynTask執(zhí)行完并且返回結果辜御,會報異常嗎?

當一個App旋轉時,整個Activity會被銷毀和重建屈张。當Activity重啟時擒权,AsyncTask中對該Activity的引用是無效的,因此onPostExecute()就不會起作用袜茧,若AsynTask正在執(zhí)行菜拓,折會報 view not attached to window manager 異常

同樣也是生命周期的問題,在 Activity 的onDestory()方法中調用Asyntask.cancal方法笛厦,讓二者的生命周期同步

問題:Activity銷毀但Task如果沒有銷毀掉纳鼎,當Activity重啟時這個AsyncTask該如何解決?

還是屏幕旋轉這個例子裳凸,在重建Activity的時候贱鄙,會回掉Activity.onRetainNonConfigurationInstance()重新傳遞一個新的對象給AsyncTask,完成引用的更新

問題:AstncTask+HttpClient與AsyncHttpClient有什么區(qū)別

8姨谷、Android啟動過程及應用啟動過程--1

分析篇:Android啟動過程圖解

Android Application啟動流程分析

Android Activity.startActivity流程簡介

問題:Android窗口設計

Android應用程序窗口設計框架介紹

問題:activity啟動過程

鏈接:activity啟動過程詳解

1.Activity中最終到startActivityForResult()(mMainThread.getApplicationThread()傳入了一個ApplicationThread檢查APT)

->Instrumentation#execStartActivity()和checkStartActivityResult()(這是在啟動了Activity之后判斷Activity是否啟動成功逗宁,例如沒有在AM中注冊那么就會報錯)

->ActivityManagerNative.getDefault().startActivity()(類似AIDL,實現(xiàn)了IAM梦湘,實際是由遠端的AMS實現(xiàn)startActivity())

->ActivityStackSupervisor#startActivityMayWait()

->ActivityStack#resumeTopActivityInnerLocked

->ActivityStackSupervisor#realStartActivityLocked()(在這里調用APT的scheduleLaunchActivity,也是AIDL瞎颗,不過是在遠端調起了本進程Application線程)

->ApplicationThread#scheduleLaunchActivity()(這是本進程的一個線程,用于作為Service端來接受AMS client端的調起)

->ActivityThread#handleLaunchActivity()(接收內部類H的消息捌议,ApplicationThread線程發(fā)送LAUNCH_ACTIVITY消息給H)

->最終在ActivityThread#performLaunchActivity()中實現(xiàn)Activity的啟動完成了以下幾件事:

2.從傳入的ActivityClientRecord中獲取待啟動的Activity的組件信息

3.創(chuàng)建類加載器哼拔,使用Instrumentation#newActivity()加載Activity對象

4.調用LoadedApk.makeApplication方法嘗試創(chuàng)建Application,由于單例所以不會重復創(chuàng)建瓣颅。

5.創(chuàng)建Context的實現(xiàn)類ContextImpl對象倦逐,并通過Activity#attach()完成數(shù)據(jù)初始化和Context建立聯(lián)系,因為Activity是Context的橋接類宫补,

最后就是創(chuàng)建和關聯(lián)window檬姥,讓Window接收的事件傳給Activity,在Window的創(chuàng)建過程中會調用ViewRootImpl的performTraversals()初始化View粉怕。

6.Instrumentation#callActivityOnCreate()->Activity#performCreate()->Activity#onCreate().onCreate()中會通過Activity#setContentView()調用PhoneWindow的setContentView()

更新界面健民。

術語:

1.ActivityManagerServices,簡稱AMS贫贝,服務端對象荞雏,負責系統(tǒng)中所有Activity的生命周期

2.ActivityThread,App的真正入口。當開啟App之后凤优,會調用main()開始運行悦陋,開啟消息循環(huán)隊列,這就是傳說中的UI線程或者叫主線程筑辨。與ActivityManagerServices配合俺驶,一起完成Activity的管理工作

3.ApplicationThread,用來實現(xiàn)ActivityManagerService與ActivityThread之間的交互棍辕。在ActivityManagerService需要管理相關Application中的Activity的生命周期時暮现,通過ApplicationThread的代理對象與ActivityThread通訊。

4.ApplicationThreadProxy楚昭,是ApplicationThread在服務器端的代理栖袋,負責和客戶端的ApplicationThread通訊。AMS就是通過該代理與ActivityThread進行通信的抚太。

5.Instrumentation塘幅,每一個應用程序只有一個Instrumentation對象,每個Activity內都有一個對該對象的引用尿贫。Instrumentation可以理解為應用進程的管家电媳,ActivityThread要創(chuàng)建或暫停某個Activity時,都需要通過Instrumentation來進行具體的操作庆亡。

6.ActivityStack匾乓,Activity在AMS的棧管理,用來記錄已經(jīng)啟動的Activity的先后關系又谋,狀態(tài)信息等拼缝。通過ActivityStack決定是否需要啟動新的進程。

7.ActivityRecord彰亥,ActivityStack的管理對象珍促,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態(tài)以及其他的管理信息剩愧。其實就是服務器端的Activity對象的映像。

8.TaskRecord娇斩,AMS抽象出來的一個“任務”的概念仁卷,是記錄ActivityRecord的棧,一個“Task”包含若干個ActivityRecord犬第。AMS用TaskRecord確保Activity啟動和退出的順序锦积。如果你清楚Activity的4種launchMode,那么對這個概念應該不陌生歉嗓。

9丰介、Loader機制

Android 深入理解Loader機制 讓APP輕裝上陣

AsyncTaskLoader設計原理大揭秘

10、安卓權限管理

11、Dalvik及ART虛擬機系列問題

MS思考:Android面試一天一題(Day 27:ART & Dalvik)

問題:什么是Dalvik虛擬機哮幢?

Dalvik虛擬機是Android平臺的核心带膀。它可以支持.dex格式的程序的運行,.dex格式是專為Dalvik設計的一種壓縮格式橙垢,可以減少整體文件尺寸垛叨,提高I/O操作的速度,適合內存和處理器速度有限的系統(tǒng)柜某。

問題:Dalvik虛擬機的作用是什么嗽元?

Dalvik虛擬機主要是完成對象生命周期管理,內存回收喂击,堆棧管理剂癌,線程管理,安全和異常管理等等重要功能翰绊。

問題:Dalvik虛擬機與JVM有什么區(qū)別

主要區(qū)別:

Dalvik是基于寄存器的佩谷,而JVM是基于的。

Dalvik運行dex文件辞做,而JVM運行java字節(jié)碼

自Android 2.2開始琳要,Dalvik支持JIT(just-in-time,即時編譯技術)秤茅。

優(yōu)化后的Dalvik較其他標準虛擬機存在一些不同特性:

1.占用更少空間

2.為簡化翻譯稚补,常量池只使用32位索引

3.標準Java字節(jié)碼實行8位堆棧指令,Dalvik使用16位指令集直接作用于局部變量。局部變量通常來自4位的“虛擬寄存器”區(qū)框喳。這樣減少了Dalvik的指令計數(shù)课幕,提高了翻譯速度。

當Android啟動時五垮,Dalvik VM 監(jiān)視所有的程序(APK)乍惊,并且創(chuàng)建依存關系樹,為每個程序優(yōu)化代碼并存儲在Dalvik緩存中放仗。Dalvik第一次加載后會生成Cache文件润绎,以提供下次快速加載,所以第一次會很慢诞挨。

Dalvik解釋器采用預先算好的Goto地址莉撇,每個指令對內存的訪問都在64字節(jié)邊界上對齊。這樣可以節(jié)省一個指令后進行查表的時間惶傻。為了強化功能, Dalvik還提供了快速翻譯器(Fast Interpreter)棍郎。

一般來說,基于堆棧的機器必須使用指令才能從堆棧上的加載和操作數(shù)據(jù),因此,相對基于寄存器的機器,它們需要更多的指令才能實現(xiàn)相同的性能银室。但是基于寄存器機器上的指令必須經(jīng)過編碼,因此,它們的指令往往更大涂佃。

Dalvik虛擬機既不支持Java SE 也不支持Java ME類庫(如:Java類,AWT和Swing都不支持)励翼。 相反,它使用自己建立的類庫(Apache Harmony Java的一個子集)。

問題:每個應用程序對應多少個Dalvik虛擬機

每一個Android應用在底層都會對應一個獨立的Dalvik虛擬機實例辜荠,其代碼在虛擬機的解釋下得以執(zhí)行 汽抚,而所有的Android應用的線程都對應一個Linux線程

問題:Art和Dalvik對比;大致工作流程侨拦。兩者有什么區(qū)別?

ART 的機制與 Dalvik 不同殊橙。在Dalvik下,應用每次運行的時候狱从,字節(jié)碼都需要通過即時編譯器(just in time 膨蛮,JIT)轉換為機器碼,這會拖慢應用的運行效率季研,而在ART 環(huán)境中敞葛,應用在第一次安裝的時候,字節(jié)碼就會預先編譯成機器碼与涡,使其成為真正的本地應用惹谐。這個過程叫做預編譯(AOT,Ahead-Of-Time)。這樣的話驼卖,應用的啟動(首次)和執(zhí)行都會變得更加快速氨肌。

問題:虛擬機原理,

Dalvik虛擬機簡要介紹和學習計劃

問題:如何自己設計一個虛擬機(內存管理酌畜,類加載怎囚,雙親委派);

問題:JVM內存模型及類加載機制桥胞;

java內存模型與類加載機制

【深入理解JVM】:類加載機制

問題:內存對象的循環(huán)引用及避免

java垃圾回收之循環(huán)引用

在Ios中比較常見恳守,用assign而不是retain聲明屬性可以避免循環(huán)引用,ARC下用弱引用也可以解決

如何避免循環(huán)引用造成的內存泄漏

12贩虾、Window和WindowManager機制

1.Window用于顯示View和接收各種事件催烘,Window有三種類型:應用Window(每個Activity對應一個Window)、子Window(不能單獨存在缎罢,附屬于特定Window)伊群、系統(tǒng)window(Toast和狀態(tài)欄)

2.Window分層級,應用Window在1-99策精、子Window在1000-1999舰始、系統(tǒng)Window在2000-2999.WindowManager提供了增刪改View三個功能。

3.Window是個抽象概念:每一個Window對應著一個View和ViewRootImpl蛮寂,Window通過ViewRootImpl來和View建立聯(lián)系,View是Window存在的實體易茬,只能通過WindowManager來訪問Window酬蹋。

4.WindowManager的實現(xiàn)是WindowManagerImpl其再委托給WindowManagerGlobal來對Window進行操作及老,其中有四個List分別儲存對應的View、ViewRootImpl范抓、WindowManger.LayoutParams和正在被刪除的View

5.Window的實體是存在于遠端的WindowMangerService中骄恶,所以增刪改Window在本端是修改上面的幾個List然后通過ViewRootImpl重繪View,通過WindowSession(每個應用一個)在遠端修改Window匕垫。

6.Activity創(chuàng)建Window:Activity會在attach()中創(chuàng)建Window并設置其回調(onAttachedToWindow()僧鲁、dispatchTouchEvent()),Activity的Window是由Policy類創(chuàng)建PhoneWindow實現(xiàn)的。然后通過Activity#setContentView()調用PhoneWindow的setContentView象泵。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末寞秃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偶惠,更是在濱河造成了極大的恐慌春寿,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忽孽,死亡現(xiàn)場離奇詭異绑改,居然都是意外死亡,警方通過查閱死者的電腦和手機兄一,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門厘线,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人出革,你說我怎么就攤上這事造壮。” “怎么了蹋盆?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵费薄,是天一觀的道長。 經(jīng)常有香客問我栖雾,道長楞抡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任析藕,我火速辦了婚禮召廷,結果婚禮上,老公的妹妹穿的比我還像新娘账胧。我一直安慰自己竞慢,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布治泥。 她就那樣靜靜地躺著筹煮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪居夹。 梳的紋絲不亂的頭發(fā)上败潦,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天本冲,我揣著相機與錄音,去河邊找鬼劫扒。 笑死檬洞,一個胖子當著我的面吹牛,可吹牛的內容都是我干的沟饥。 我是一名探鬼主播添怔,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贤旷!你這毒婦竟也來了广料?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤遮晚,失蹤者是張志新(化名)和其女友劉穎性昭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體县遣,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡糜颠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了萧求。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片其兴。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夸政,靈堂內的尸體忽然破棺而出元旬,到底是詐尸還是另有隱情,我是刑警寧澤守问,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布匀归,位于F島的核電站,受9級特大地震影響耗帕,放射性物質發(fā)生泄漏穆端。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一仿便、第九天 我趴在偏房一處隱蔽的房頂上張望体啰。 院中可真熱鬧,春花似錦嗽仪、人聲如沸荒勇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沽翔。三九已至,卻和暖如春窿凤,著一層夾襖步出監(jiān)牢的瞬間仅偎,已是汗流浹背西潘。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哨颂,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓相种,卻偏偏與公主長得像威恼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子寝并,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內容