Android面試之第三方源碼解析

面試專(zhuān)題我放在git上了图甜,地址Github 歡迎fork然后一起更新

0,Okhttp相關(guān)

操作:

  • 創(chuàng)建一個(gè)OkhttpClient對(duì)象
  • 然后創(chuàng)建一個(gè)request對(duì)象,通過(guò)內(nèi)部類(lèi)Builder調(diào)用生成的Request對(duì)象丽惶,對(duì)象攜帶請(qǐng)求參數(shù)
  • 創(chuàng)建一個(gè)Call對(duì)象譬胎,調(diào)用execute(同步差牛,線程阻塞)/enqueue(異步)(回調(diào)方法是運(yùn)行在子線程中,記住無(wú)法更新UI堰乔,得通過(guò)handler)

優(yōu)點(diǎn):

1偏化,Okhttp的最大并發(fā)量為64,比volley的只有4個(gè)強(qiáng)很多倍

2镐侯,使用連接池技術(shù)侦讨,支持5個(gè)并發(fā)的socket連接,默認(rèn)keepAlive時(shí)間為5分鐘苟翻,解決TCP握手揮手的效率問(wèn)題韵卤,減少握手次數(shù)

3,支持Gzip壓縮崇猫,且操作對(duì)用戶(hù)透明沈条,可以通過(guò)header設(shè)置,在發(fā)起請(qǐng)求的時(shí)候自動(dòng)加入header诅炉,Accept-Encoding:gzip,而我們的服務(wù)器返回的時(shí)候header中有Content-Encoding:gzip

4拍鲤,利用響應(yīng)緩存來(lái)避免重復(fù)的網(wǎng)絡(luò)請(qǐng)求

5贴谎,很方便的添加攔截器,通常情況下季稳,攔截器用來(lái)添加擅这,移除,轉(zhuǎn)換請(qǐng)求和響應(yīng)的頭部信息景鼠,比如添加公共參數(shù)等

6仲翎,請(qǐng)求失敗自動(dòng)重連,發(fā)生異常時(shí)重連铛漓,看源碼調(diào)用recover方法重連了一次

7. 支持SPDY協(xié)議(SPDY是Google開(kāi)發(fā)的基于TCP的應(yīng)用層協(xié)議溯香,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度浓恶,優(yōu)化用戶(hù)的網(wǎng)絡(luò)使用體驗(yàn)玫坛。SPDY并不是一種用于替代HTTP的協(xié)議,而是對(duì)HTTP協(xié)議的增強(qiáng)包晰。新協(xié)議的功能包括數(shù)據(jù)流的多路復(fù)用湿镀、請(qǐng)求優(yōu)先級(jí)以及HTTP報(bào)頭壓縮。谷歌表示伐憾,引入SPDY協(xié)議后勉痴,在實(shí)驗(yàn)室測(cè)試中頁(yè)面加載速度比原先快64%)

8.使用Okio來(lái)簡(jiǎn)化數(shù)據(jù)的訪問(wèn)與存儲(chǔ),提高性能

缺點(diǎn):

1.消息回來(lái)需要切到主線程树肃,主線程要自己去寫(xiě)蒸矛。

2.調(diào)用比較復(fù)雜,需要自己進(jìn)行封裝胸嘴。

3.緩存失效:網(wǎng)絡(luò)請(qǐng)求時(shí)一般都會(huì)獲取手機(jī)的一些硬件或網(wǎng)絡(luò)信息雏掠,比如使用的網(wǎng)絡(luò)環(huán)境。同時(shí)為了信息傳輸?shù)陌踩粤酉瘢赡苓€會(huì)對(duì)請(qǐng)求進(jìn)行加密乡话。在這些情況下OkHttp的緩存系統(tǒng)就會(huì)失效了,導(dǎo)致用戶(hù)在無(wú)網(wǎng)絡(luò)情況下不能訪問(wèn)緩存

框架中用到了那些設(shè)計(jì)模式:

1.最明顯的Builder設(shè)計(jì)模式驾讲,如構(gòu)建對(duì)象OkHttpClient蚊伞,還有單利模式

2.工廠方法模式,如源碼中的接口Call

3.觀察者模式如EventListener吮铭,監(jiān)聽(tīng)請(qǐng)求和響應(yīng)

4.策略模式

5.責(zé)任鏈模式时迫,如攔截器

OK的網(wǎng)絡(luò)請(qǐng)求緩存如何處理?

網(wǎng)絡(luò)緩存優(yōu)先考慮強(qiáng)制緩存谓晌,再考慮對(duì)比緩存

首先判斷強(qiáng)制緩存中的數(shù)據(jù)是否在有效期內(nèi)掠拳,如果在,就直接用緩存纸肉,如過(guò)了有效期溺欧,則進(jìn)入對(duì)比緩存

在對(duì)比緩存過(guò)程中喊熟,判斷ETag是否有變動(dòng),如果服務(wù)端返回沒(méi)有變動(dòng)姐刁,說(shuō)明資源未改變芥牌,使用緩存。如果有變動(dòng)聂使,判斷Last-Modified壁拉。

判斷Last-Modified,如果服務(wù)端對(duì)比資源的上次修改時(shí)間沒(méi)有變化柏靶,則用緩存弃理,否則重新請(qǐng)求服務(wù)端的數(shù)據(jù),并作緩存工作屎蜓。

Okhttp源碼解析

image.png

Okhttp構(gòu)造的時(shí)候會(huì)new 一個(gè)dipatcher對(duì)象

同步請(qǐng)求:dispatcher(分發(fā)器--保存同步請(qǐng)求痘昌,移除異步請(qǐng)求),execute
異步請(qǐng)求:dispatcher(一個(gè)等待請(qǐng)求隊(duì)列炬转,一個(gè)正在請(qǐng)求隊(duì)列辆苔,一個(gè)線程池),enqueue

判斷當(dāng)前call返吻,封裝一個(gè)AsyncCall對(duì)象姑子,通過(guò)client.dispatcher().enqueue()請(qǐng)求

通過(guò) getResponseWithInterceptorChain()

dispatcher的作用為維護(hù)請(qǐng)求的狀態(tài)乎婿,并維護(hù)一個(gè)線程池测僵,用于執(zhí)行請(qǐng)求。

ok相對(duì)其他的來(lái)說(shuō)高效的原因:內(nèi)部有個(gè)異步的線程池用來(lái)維護(hù)

同步請(qǐng)求直接一個(gè)隊(duì)列谢翎?

直接runningSyncCalls.add(call)捍靠;不再判斷,直接添加森逮,因?yàn)橥秸?qǐng)求不需要像異步還要判斷

異步請(qǐng)求為什么需要2個(gè)隊(duì)列榨婆?

類(lèi)似生產(chǎn)者消費(fèi)者模型,生產(chǎn)者只生產(chǎn)褒侧,消費(fèi)者只消費(fèi)良风,因?yàn)楫惒接凶畲筮\(yùn)行數(shù)64限制,所以超過(guò)數(shù)量后需要有緩存?zhèn)}庫(kù)闷供;

  • Dispatcher 生產(chǎn)者烟央,
  • ExecutorService 消費(fèi)者池,
  • Deque<readyAsyncCalls>緩存歪脏,
  • Deque<runningAsyncCalls>正在運(yùn)行的任務(wù)


    image.png

開(kāi)啟一個(gè)線程池疑俭,然后

不管同步請(qǐng)求還是異步請(qǐng)求都是通過(guò)攔截器鏈發(fā)起請(qǐng)求

然后通過(guò)HttpEngine發(fā)起請(qǐng)求并讀取結(jié)果,有緩存就進(jìn)緩存文件系統(tǒng)婿失,無(wú)緩存就走網(wǎng)絡(luò)請(qǐng)求钞艇,然后讀取Response最后獲取結(jié)果


image.png

1啄寡,retrofit源碼解析

Retrofit底層是基于Okhttp實(shí)現(xiàn)的,使用運(yùn)行時(shí)注解的方式

1哩照、 原理

通過(guò)java接口以及注解來(lái)描述網(wǎng)絡(luò)請(qǐng)求挺物,并用動(dòng)態(tài)代理的方式生成網(wǎng)絡(luò)請(qǐng)求的request,然后通過(guò)client調(diào)用相應(yīng)的網(wǎng)絡(luò)框架(默認(rèn)okhttp)去發(fā)起網(wǎng)絡(luò)請(qǐng)求飘弧,并將返回的response通過(guò)converterFactorty轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)model姻乓,最后通過(guò)call adapter轉(zhuǎn)換成其他數(shù)據(jù)方式(如rxjava Observable)

2、 Retrofit流程

(1)通過(guò)解析 網(wǎng)絡(luò)請(qǐng)求接口的注解 配置 網(wǎng)絡(luò)請(qǐng)求參數(shù)

(2)通過(guò) 動(dòng)態(tài)代理 生成 網(wǎng)絡(luò)請(qǐng)求對(duì)象

(3)通過(guò) 網(wǎng)絡(luò)請(qǐng)求適配器 將 網(wǎng)絡(luò)請(qǐng)求對(duì)象 進(jìn)行平臺(tái)適配

(4)通過(guò) 網(wǎng)絡(luò)請(qǐng)求執(zhí)行器 發(fā)送網(wǎng)絡(luò)請(qǐng)求

(5)通過(guò) 數(shù)據(jù)轉(zhuǎn)換器 解析服務(wù)器返回的數(shù)據(jù)

(6)通過(guò) 回調(diào)執(zhí)行器 切換線程(子線程 ->>主線程)

(7)用戶(hù)在主線程處理返回結(jié)果

3眯牧、 Retrofit優(yōu)點(diǎn)

1.可以配置不同HTTP client來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求蹋岩,如okhttp、httpclient等学少;

2.請(qǐng)求的方法參數(shù)注解都可以定制剪个;

3.支持同步、異步和RxJava版确;

4.超級(jí)解耦扣囊;

5.可以配置不同的反序列化工具來(lái)解析數(shù)據(jù),如json绒疗、xml等

6.框架使用了很多設(shè)計(jì)模式

如何使用:

  • 在retrofit中通過(guò)一個(gè)接口作為http請(qǐng)求的api接口
  • 創(chuàng)建一個(gè)Retrofit實(shí)例
  • 調(diào)用api接口

Retrofit動(dòng)態(tài)代理:

  • 首先侵歇,通過(guò)method把它轉(zhuǎn)換成ServiceMethod
  • 然后,通過(guò)serviceMethod吓蘑,args獲取到okHttpCall對(duì)象
  • 最后惕虑,再吧okHttpCall進(jìn)一步封裝并返回Call對(duì)象

源碼:

  • 創(chuàng)建一個(gè)retrofit對(duì)象
  • 通過(guò)Retrofit.create()方法把定義的接口轉(zhuǎn)換成接口實(shí)例,并使用接口中的方法
  • 最終的網(wǎng)絡(luò)請(qǐng)求調(diào)用okhttp

2磨镶,volley源碼解析

eg:https://a.codekk.com/detail/Android/grumoon/Volley%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90

通過(guò)new RequestQueue() 函數(shù)新建并啟動(dòng)一個(gè)請(qǐng)求隊(duì)列RequestQueue后溃蔫,只需往這個(gè)RequestQueue不斷add Request即可。

2個(gè)請(qǐng)求隊(duì)列 CacheDispatcher琳猫,NetworkDispatcher

先判斷緩存伟叛,如果有且沒(méi)過(guò)期,就從緩存拿數(shù)據(jù)

沒(méi)有緩存脐嫂,就從NetworkDispatcher中獲取并保持在hashmap

默認(rèn)情況下统刮,volley中開(kāi)啟四個(gè)網(wǎng)絡(luò)調(diào)度線程和一個(gè)緩存調(diào)度線程,首先請(qǐng)求會(huì)加入緩存隊(duì)列账千,緩存調(diào)度線程從緩存隊(duì)列中取出線程侥蒙,如果找到該請(qǐng)求的緩存就

直接讀取該緩存并解析,然后回調(diào)給主線程蕊爵,如果沒(méi)有找到緩存的響應(yīng)辉哥,則將這個(gè)請(qǐng)求加入網(wǎng)絡(luò)隊(duì)列,然后網(wǎng)絡(luò)調(diào)度線程會(huì)輪詢(xún)?nèi)〕鼍W(wǎng)絡(luò)隊(duì)列中的請(qǐng)求,發(fā)起http請(qǐng)求醋旦,解析響應(yīng)并將響應(yīng)存入緩存恒水,回調(diào)給主線程。

volley基于請(qǐng)求隊(duì)列饲齐,volley的網(wǎng)絡(luò)請(qǐng)求線程池默認(rèn)大小為4钉凌,意味著只能并發(fā)進(jìn)行4個(gè)請(qǐng)求,大于4個(gè)會(huì)排在隊(duì)列中捂人,并發(fā)量太小御雕,所以適合請(qǐng)求高頻率

volley下載文件會(huì)將流入內(nèi)存中(是一個(gè)小于4k的緩存池),大文件會(huì)導(dǎo)致內(nèi)存溢出滥搭,所以不能下載大文件不能上傳大文件酸纲,比如上傳了四個(gè)大文件,同時(shí)占用了volley的四個(gè)線程導(dǎo)致其他網(wǎng)絡(luò)請(qǐng)求都阻塞在隊(duì)列中瑟匆,造成反應(yīng)慢的現(xiàn)象闽坡。

3,Butterknife原理

依托Java的注解機(jī)制來(lái)實(shí)現(xiàn)輔助代碼生成的框架愁溜。沒(méi)有采用反射機(jī)制疾嗅,用的是編譯時(shí)再生成代碼

  1. 開(kāi)始 會(huì)掃描Java代碼中所有的ButterKnife注解
  2. ButterKnifeProcessor 生成-><className>$$ViewBinder
  3. 調(diào)用bind方法加載深沉的ViewBinder類(lèi)

注意:注解的方法必須是public,protected冕象,不能是private代承,會(huì)影響性能,而且private是反射注入的

4渐扮,Glide源碼解析

1)Glide.with(context)創(chuàng)建了一個(gè)RequestManager论悴,同時(shí)實(shí)現(xiàn)加載圖片與組件生命周期綁定:在Activity上創(chuàng)建一個(gè)透明的ReuqestManagerFragment加到FragmentManager中,通過(guò)添加的Fragment感知Activty\Fragment的生命周期席爽。因?yàn)樘砑拥紸ctivity中的Fragment會(huì)跟隨Activity的生命周期意荤。在RequestManagerFragment中的相應(yīng)生命周期方法中通過(guò)liftcycle傳遞給在lifecycle中注冊(cè)的LifecycleListener

2)RequestManager.load(url) 創(chuàng)建了一個(gè)RequestBuilder<T>對(duì)象 T可以是Drawable對(duì)象或是ResourceType等

  1. RequestBuilder.into(view)

-->into(glideContext.buildImageViewTarget(view, transcodeClass))返回的是一個(gè)DrawableImageViewTarget, Target用來(lái)最終展示圖片的啊片,buildImageViewTarget-->ImageViewTargetFactory.buildTarget()根據(jù)傳入class參數(shù)不同構(gòu)建不同的Target對(duì)象只锻,這個(gè)Class是根據(jù)構(gòu)建Glide時(shí)是否調(diào)用了asBitmap()方法,如果調(diào)用了會(huì)構(gòu)建出BitmapImageViewTarget紫谷,否則構(gòu)建的是GlideDrawableImageViewTarget對(duì)象齐饮。

-->GenericRequestBuilder.into(Target),該方法進(jìn)行了構(gòu)建Request,并用RequestTracker.runRequest()

Request request = buildRequest(target);//構(gòu)建Request對(duì)象笤昨,Request是用來(lái)發(fā)出加載圖片的祖驱,它調(diào)用了buildRequestRecursive()方法以,內(nèi)部調(diào)用了GenericRequest.obtain()方法

target.setRequest(request);

lifecycle.addListener(target);

requestTracker.runRequest(request);//判斷Glide當(dāng)前是不是處于暫停狀態(tài)瞒窒,若不是則調(diào)用Request.begin()方法來(lái)執(zhí)行Request捺僻,否則將Request添加到待執(zhí)行隊(duì)列里,等暫停態(tài)解除了后再執(zhí)行

-->GenericRequest.begin()

1)onSizeReady()--> Engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,

        priority, isMemoryCacheable, diskCacheStrategy, this) --> a)先構(gòu)建EngineKey; b) loadFromCache從緩存中獲取EngineResource,如果緩存中獲取到cache就調(diào)用cb.onResourceReady(cached)匕坯; c)如果緩存中不存在調(diào)用loadFromActiveResources從active中獲取束昵,如果獲取到就調(diào)用cb.onResourceReady(cached);d)如果active中也不存在葛峻,調(diào)用EngineJob.start(EngineRunnable), 從而調(diào)用decodeFromSource()/decodeFromCache()-->如果是調(diào)用decodeFromSource()-->ImageVideoFetcher.loadData()-->HttpUrlFetcher()調(diào)用HttpUrlConnection進(jìn)行網(wǎng)絡(luò)請(qǐng)求資源-->得于InputStream()后,調(diào)用decodeFromSourceData()-->loadProvider.getSourceDecoder().decode()方法解碼-->GifBitmapWrapperResourceDecoder.decode()-->decodeStream()先從流中讀取2個(gè)字節(jié)判斷是GIF還是普通圖锹雏,若是GIF調(diào)用decodeGifWrapper()來(lái)解碼,若是普通靜圖則調(diào)用decodeBitmapWrapper()來(lái)解碼-->bitmapDecoder.decode()

6术奖、Glide使用什么緩存礁遵?

  1. 內(nèi)存緩存:LruResourceCache(memory)+弱引用activeResources

Map<Key, WeakReference<EngineResource<?>>> activeResources正在使用的資源,當(dāng)acquired變量大于0采记,說(shuō)明圖片正在使用佣耐,放到activeResources弱引用緩存中,經(jīng)過(guò)release()后唧龄,acquired=0,說(shuō)明圖片不再使用晰赞,會(huì)把它放進(jìn)LruResourceCache中

2)磁盤(pán)緩存:DiskLruCache,這里分為Source(原始圖片)和Result(轉(zhuǎn)換后的圖片)

第一次獲取圖片,肯定網(wǎng)絡(luò)取选侨,然后存active\disk中掖鱼,再把圖片顯示出來(lái),第二次讀取相同的圖片援制,并加載到相同大小的imageview中戏挡,會(huì)先從memory中取,沒(méi)有再去active中獲取晨仑。如果activity執(zhí)行到onStop時(shí)褐墅,圖片被回收,active中的資源會(huì)被保存到memory中洪己,active中的資源被回收妥凳。當(dāng)再次加載圖片時(shí),會(huì)從memory中取答捕,再放入active中逝钥,并將memory中對(duì)應(yīng)的資源回收。

之所以需要activeResources拱镐,它是一個(gè)隨時(shí)可能被回收的資源艘款,memory的強(qiáng)引用頻繁讀寫(xiě)可能造成內(nèi)存激增頻繁GC,而造成內(nèi)存抖動(dòng)沃琅。資源在使用過(guò)程中保存在activeResources中哗咆,而activeResources是弱引用,隨時(shí)被系統(tǒng)回收益眉,不會(huì)造成內(nèi)存過(guò)多使用和泄漏晌柬。

7姥份、Glide內(nèi)存緩存如何控制大小年碘?

Glide內(nèi)存緩存最大空間(maxSize)=每個(gè)進(jìn)程可用最大內(nèi)存0.4(低配手機(jī)是 每個(gè)進(jìn)程可用最大內(nèi)存0.33)

磁盤(pán)緩存大小是250MB int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;

5殿衰,leakcanary、blockcanary

6盛泡,eventbus

Android事件發(fā)布訂閱框架

事件傳遞既可以用于Android四大組件間的通訊

EventBus


image.png

1闷祥,定義事件Event

2,準(zhǔn)備訂閱者

3傲诵,訂閱者同時(shí)需要在總線上注冊(cè)和注銷(xiāo)自己

4凯砍,發(fā)送事件

通過(guò)構(gòu)造者模式構(gòu)建EventBusBuilder,ThreadMode有四個(gè)線程拴竹,POSTING悟衩,MAIN,BACKGROUND栓拜,ASYNC座泳,

7,dagger2

8幕与,rxjava

Rxjava是基于響應(yīng)式編程挑势,基于事件流,實(shí)現(xiàn)異步操作的庫(kù)啦鸣。

RxJava原理是基于一種擴(kuò)展的觀察者模式潮饱,有四種角色:被觀察者Observable 觀察者Observer 訂閱subscribe 事件Event。RxJava原理可總結(jié)為:被觀察者Observable通過(guò)訂閱(subscribe)按順序發(fā)送事件(Emitter)給觀察者(Observer)诫给, 觀察者按順序接收事件&作出相應(yīng)的響應(yīng)動(dòng)作香拉。

9,picasso

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末中狂,一起剝皮案震驚了整個(gè)濱河市凫碌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胃榕,老刑警劉巖盛险,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異勤晚,居然都是意外死亡枉层,警方通過(guò)查閱死者的電腦和手機(jī)氛魁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)窘奏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熄云,“玉大人,你說(shuō)我怎么就攤上這事挺邀。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵端铛,是天一觀的道長(zhǎng)泣矛。 經(jīng)常有香客問(wèn)我,道長(zhǎng)禾蚕,這世上最難降的妖魔是什么您朽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮换淆,結(jié)果婚禮上哗总,老公的妹妹穿的比我還像新娘。我一直安慰自己倍试,他們只是感情好讯屈,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著县习,像睡著了一般涮母。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躁愿,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天叛本,我揣著相機(jī)與錄音,去河邊找鬼彤钟。 笑死炮赦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的样勃。 我是一名探鬼主播吠勘,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼峡眶!你這毒婦竟也來(lái)了剧防?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辫樱,失蹤者是張志新(化名)和其女友劉穎峭拘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體狮暑,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸡挠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搬男。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拣展。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缔逛,靈堂內(nèi)的尸體忽然破棺而出备埃,到底是詐尸還是另有隱情姓惑,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布按脚,位于F島的核電站于毙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辅搬。R本人自食惡果不足惜唯沮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堪遂。 院中可真熱鬧介蛉,春花似錦、人聲如沸蚤氏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)竿滨。三九已至佳恬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間于游,已是汗流浹背毁葱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贰剥,地道東北人倾剿。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蚌成,于是被迫代替她去往敵國(guó)和親前痘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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