【干貨】組件化開發(fā),MVP模式項(xiàng)目實(shí)戰(zhàn)(更新中……)

分析某OTA平臺Android客戶端建立模擬架構(gòu)

一、工作回顧

一年中根據(jù)新酒店業(yè)務(wù)開發(fā)不斷的對架構(gòu)進(jìn)行優(yōu)化迭代肪凛,同時(shí)也綜合了“XXX客戶端”現(xiàn)有的業(yè)務(wù)場景以及現(xiàn)有項(xiàng)目結(jié)構(gòu)進(jìn)行分析,最終建立了AndroidModuleDevPro架構(gòu)和開發(fā)模式辽社,項(xiàng)目基于MVPArms伟墙、組件化開發(fā)的基礎(chǔ)上,用來解決因?yàn)闃I(yè)務(wù)的增加導(dǎo)致項(xiàng)目的體積變得龐大而難以維護(hù)滴铅,同時(shí)也增強(qiáng)了團(tuán)隊(duì)協(xié)作的靈活性戳葵,可以更快捷有效的開發(fā)、測試汉匙、迭代拱烁。

二、組件化

基于現(xiàn)在的“XXX戶端”分析噩翠,現(xiàn)有業(yè)務(wù)有:機(jī)票戏自、酒店、火車票伤锚、貴賓廳擅笔、專車、門票见芹、管家金卡剂娄、代換登機(jī)牌、安檢通道玄呛、延誤險(xiǎn)理賠阅懦、會員商城、行程管理徘铝、優(yōu)秀員工耳胎、航班動態(tài)、個(gè)人中心惕它、我的錢包怕午、常用信息、消息中心淹魄、訂單中心郁惜、特價(jià)機(jī)票、特價(jià)酒店等甲锡;

從上述功能可以看出我們的APP的業(yè)務(wù)覆蓋已經(jīng)非常的全面兆蕉,所以這也導(dǎo)致我們項(xiàng)目的代碼量的猛增羽戒,由于架構(gòu)設(shè)計(jì)沒有跟上業(yè)務(wù)的增長,導(dǎo)致了我們現(xiàn)有的幾個(gè)問題:采用單一項(xiàng)目結(jié)構(gòu)項(xiàng)目代碼冗余虎韵、模塊間耦合度高不易于迭代維護(hù)易稠、開發(fā)調(diào)試運(yùn)行時(shí)間漫長、人員的分配無法隨機(jī)調(diào)動且代碼閱讀成本較高包蓝、無法單一業(yè)務(wù)模塊測試導(dǎo)致測試流程繁瑣等驶社;

所以如果能有一種開發(fā)模式可以將每一個(gè)業(yè)務(wù)單做一個(gè)APP運(yùn)行豈不是可以節(jié)省不少構(gòu)建的時(shí)間,并且還可以使得項(xiàng)目結(jié)構(gòu)更加的清晰测萎。

三亡电、組件拆解

基于“問題描述”我們不難看出,“客戶端”每一個(gè)業(yè)務(wù)單獨(dú)抽離都可以作為一個(gè)完整的APP獨(dú)立開發(fā)運(yùn)行硅瞧,所以我們通過這個(gè)思路先對項(xiàng)目進(jìn)行較大粒度的劃分逊抡,劃分后的效果如下:

客戶端項(xiàng)目架構(gòu).png

配圖說明:

  • lib_common:架構(gòu)基礎(chǔ),提供公用的架構(gòu)零酪、工具類等,不參與任何業(yè)務(wù)處理拇勃;

  • lib_protobuf:數(shù)據(jù)實(shí)體四苇,提供數(shù)據(jù)實(shí)體、不參與任何業(yè)務(wù)處理方咆;

  • module_app:宿主月腋,不參與任何業(yè)務(wù)處理;

  • module_main:主框架瓣赂,提供應(yīng)用的基礎(chǔ)條件榆骚,一般只用包含、啟動頁煌集、主視圖框架等妓肢;

  • module_user:用戶組件,用戶相關(guān)信息苫纤,比如:登陸碉钠、注冊、修改信息卷拘、常用信息等喊废,同時(shí)也會向外部提供公用數(shù)據(jù)的獲取栗弟;

  • module_hotel:酒店組件污筷,酒店的查詢、列表乍赫、詳情瓣蛀、下單陆蟆、訂單管理等;

  • module_flight_info:航班動態(tài)揪惦,查詢遍搞、列表、詳情器腋;

  • module_tickets:門票組件溪猿,查詢、列表纫塌、詳情诊县、下單、訂單管理措左;

  • module_air_ticket:機(jī)票組件依痊,查詢、列表怎披、詳情胸嘁、下單、訂單管理凉逛;

  • module_train_ticket:火車票組件性宏,查詢、列表状飞、詳情毫胜、下單、訂單管理诬辈;

  • module_insurance:延誤險(xiǎn)理賠組件酵使,查詢、列表焙糟、詳情口渔、下單、訂單管理穿撮;

  • module_bording_pass:代換登機(jī)牌搓劫,查詢、列表混巧、詳情枪向、下單、訂單管理咧党;

  • module_message:消息中心秘蛔,查詢、列表、詳情深员、下單负蠕、訂單管理;

  • 根據(jù)業(yè)務(wù)動態(tài)添加其它

當(dāng)我們將項(xiàng)目拆分為上述結(jié)構(gòu)之后倦畅,就可以針對每一個(gè)組件進(jìn)行單獨(dú)的調(diào)試遮糖、開發(fā)、迭代升級等操作叠赐,并且不會影響到其他的模塊欲账,那么在實(shí)際的開發(fā)過程中怎么去實(shí)現(xiàn)呢?

Android Studio 是基于Gradle構(gòu)建的項(xiàng)目芭概,Android常用的Module類型有Android Library赛不、Phone&Table Module、Java Library這三個(gè)罢洲,可以進(jìn)行單獨(dú)運(yùn)行的模式為Phone&Table Module踢故、其余的兩個(gè)模式可以作為引入關(guān)系引入到項(xiàng)目中,所以我們基于這個(gè)特性對項(xiàng)目的Module類型進(jìn)行動態(tài)的切換從而達(dá)到組件化中“集成模式”&“組建模式”的切換效果惹苗,思路理清了那么就直接上代碼:

每個(gè)要作為組件模塊的build.gradle文件都要添加下面的代碼:

//isModule.toBoolean()是我們在gradle.properties文件中聲明的一個(gè)變量
if (isModule.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

gradle.properties文件

# 每次更改“isModule”的值后殿较,需要點(diǎn)擊 "Sync Project" 按鈕
# isModule是“集成開發(fā)模式”和“組件開發(fā)模式”的切換開關(guān)
isModule=false

最后打包發(fā)布的時(shí)候我們肯定是整包發(fā)布,所以作為宿主的module_app要將需要整合的組件引入進(jìn)來桩蓉,引用關(guān)系使用下面的代碼:

module_app組件中的build.gradle文件:

//依賴設(shè)置
dependencies {
    //引入基礎(chǔ)的開發(fā)包
    implementation project(':lib_base')
    //isModule.toBoolean()是我們在gradle.properties文件中聲明
    if (!isModule.toBoolean()) {
        implementation project(':module_main')
        implementation project(':module_hotel')
        implementation project(':module_order')
        implementation project(':module_user')
        //………其它的你想引入進(jìn)來的模塊
    }
}

這里有一個(gè)點(diǎn)需要注意斜脂,在Gradle 4.X之后依賴的dependencies關(guān)鍵字發(fā)生了變化:

api:完全等同于compile指令,沒區(qū)別触机,你將所有的compile改成api,完全沒有錯(cuò)玷或。

implementation:這個(gè)指令的特點(diǎn)就是儡首,對于使用了該命令編譯的依賴,對該項(xiàng)目有依賴的項(xiàng)目將無法訪問到使用該命令編譯的依賴中的任何程序偏友,也就是將該依賴隱藏在內(nèi)部蔬胯,而不對外部公開。

舉個(gè)例子:

比如我在一個(gè)libiary中使用implementation依賴了gson庫位他,然后我的主項(xiàng)目依賴了libiary氛濒,那么,我的主項(xiàng)目就無法訪問gson庫中的方法鹅髓。這樣的好處是編譯速度會加快舞竿,推薦使用implementation的方式去依賴,如果你需要提供給外部訪問窿冯,那么就使用api依賴即可

在Google IO 相關(guān)話題的中提到了一個(gè)建議骗奖,就是依賴首先應(yīng)該設(shè)置為implementation的,如果沒有錯(cuò),那就用implementation执桌,如果有錯(cuò)鄙皇,那么使用api指令,這樣會使編譯速度增快仰挣。

所以在組件build.gradle中我們推薦下面的配置:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':lib_base')
}

解決了module類型的動態(tài)配置之后我們將會面臨另一個(gè)問題伴逸,就是“組件模式”“集成模式”下的配置切換問題,為什么要說這個(gè)問題呢膘壶?原因就是“組件模式”下我們會模擬很多的數(shù)據(jù)错蝴,讓當(dāng)前的組件處于仿真環(huán)境下,方便我們的調(diào)試開發(fā)香椎。但是當(dāng)我們要進(jìn)行“集成模式”開發(fā)的時(shí)候這些配置信息都是無用的漱竖,甚至?xí)绊懳覀兊募蓸?gòu)建,所以就要“組件模式”“集成模式”下的配置進(jìn)行分離處理畜伐,具體怎么做馍惹?配置如下:

在組件的build.gradle文件中

android {
    //重新設(shè)置資源指向
    sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
                //組件模式下將組件使用的java目錄導(dǎo)入進(jìn)來
                java.srcDirs 'src/main/module/debug', 'src/main/java'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
                //集成開發(fā)模式只保留原有的java目錄
                java.srcDirs 'src/main/java'
            }
        }
    }
}

組件內(nèi)部結(jié)構(gòu)是下面這樣的:

image.png

經(jīng)過上面的幾個(gè)步驟項(xiàng)目組件化的結(jié)構(gòu)基本級已經(jīng)確立下來了,接下來我們就可以為所欲為的添加新的組件到我們的項(xiàng)目中玛界,而不必?fù)?dān)心這個(gè)組件對別的組件的影響万矾。

四、組件通信

組件拆解完成之項(xiàng)目看起來確實(shí)清爽了不少慎框,但是噩夢也隨之而來良狈。由于我們的組件是相互獨(dú)立的,所以……頁面之間怎么傳值笨枯?頁面怎么跳轉(zhuǎn)薪丁?Fragment怎么加載?模塊之間怎么通信馅精?等等一些問題隨之而來严嗜。

Activity跳轉(zhuǎn)的問題?

在不破壞組件化結(jié)構(gòu)的前提下洲敢,我們首先想到的應(yīng)該是隱式跳轉(zhuǎn)漫玄,通過在AndroidMainfest.xml文件中注冊過濾器

<activity android:name=".CategoryActivity" >
    <intent-filter>
        <action android:name="customer_action_here" />
    </intent-filter>
</activity>

在代碼中使用下面代碼進(jìn)行跳轉(zhuǎn)操作

//創(chuàng)建一個(gè)隱式的 Intent 對象:Category 類別  
Intent intent = new Intent();
intent.setAction("customer_action_here");
startActivity(intent);

看似我們好像友好的解決了這個(gè)問題,先放著我們進(jìn)行下一個(gè)問題压彭。

Fragment怎么加載睦优?

主框架UI一般都是聚合了多個(gè)組件的內(nèi)部Fragment進(jìn)行展示的,這個(gè)時(shí)候又當(dāng)如何使用呢壮不?

結(jié)合Java反射機(jī)制汗盘,可以直接反射出類然后創(chuàng)建對象來使用,由于代碼量比較大這里就不展開講解询一。但是問題好像是解決了衡未。

模塊間通信尸执?

用戶信息我們在很多的頁面都會用到,但是我們建立了User組件缓醋,信息被隔離到了User組件內(nèi)部如失,如果別的組件想要使用我們的User組件內(nèi)的信息怎么辦?

比較簡單的就是將這種數(shù)據(jù)操作封裝到lib_base中這樣所有的組件就都可以直接使用了送粱,但是這樣無形中增加了lib_base對業(yè)務(wù)的管理這并不是最好的實(shí)現(xiàn)褪贵,那么還有什么方式可以解決這個(gè)問題呢?

可以在lib_base中建立業(yè)務(wù)接口UserInfoService抗俄,同時(shí)在里面編寫模板方法方法:

public interface UserInfoService  {
    boolean isLogin();

    UserInfo getUserInfo();

    String getOpenId();
}

在User組件中進(jìn)行實(shí)現(xiàn):

public class UserInfoServiceImpl implements UserInfoService {

    @Override
    public boolean isLogin() {
        return SpUserInfo.isLogin();
    }

    @Override
    public UserInfo getUserInfo() {
        return SpUserInfo.getUserInfo();
    }

    @Override
    public String getOpenId() {
        return SpUserInfo.getOpenId();
    }
}

然后再使用java的反射機(jī)制對實(shí)現(xiàn)了UserInfoService接口的類進(jìn)行實(shí)例化脆丁,在調(diào)用方使用父類接口UserInfoService引用,由于接口直接引用的是一個(gè)實(shí)例化后的對象动雹,這個(gè)時(shí)候我們是直接可以通過引用關(guān)系調(diào)用到內(nèi)部方法的槽卫。從而模塊間數(shù)據(jù)通訊的問題也得到了解決。

問題是解決了胰蝠,那么實(shí)際開發(fā)好不好用呢歼培?

總結(jié)一下,頁面跳轉(zhuǎn)都要顯示的指定一個(gè)隱式跳轉(zhuǎn)的意圖茸塞,清單文件還要去注冊對應(yīng)的攔截過濾躲庄。而如果遇到了Fragment就更加麻煩,首先要去反射指定的Fragment钾虐,然后才能使用噪窘。接著就是模塊間的數(shù)據(jù)通訊,也是要先建立一個(gè)頂層接口效扫,然后要去手動的反射進(jìn)行實(shí)例化倔监,接著才能使用。

上述的操作每次使用都要進(jìn)行一編菌仁,無形中增加了代碼的冗余浩习,且維護(hù)性極差,所以我們就要將這些操作全都封裝到一個(gè)工具框架中掘托,使用的時(shí)候就幾代碼就可以完成響應(yīng)的操作。

原理我們了解了籍嘹,封裝的原理我們也想明白了闪盔,這里也是為了不重復(fù)的造輪子就直接使用阿里巴巴開源出來的ARouter進(jìn)行解耦后的頁面跳轉(zhuǎn)、Fragment初始化加載辱士、頁面?zhèn)髦底⑷肜嵯啤⒔M件件通信。

使用方式這里不贅述颂碘,請參見官方地址ARouter异赫。

五、ARouter遇坑

經(jīng)過了上面的操作,組件化的雛形終于建立起來了塔拳,那么是不是就可以愉快的擼代碼呢鼠证?

如果你認(rèn)為可以的話那么我只能說,少年你還是太天真靠抑。

由于解決組件通信問題使用的是ARouter解決方案量九,它可以很好的幫我們生成一些中間代碼,讓我們可以用最少代碼量實(shí)現(xiàn)功能颂碧,但是他有一個(gè)弊端荠列,就是ARouter為我們生成的代碼是統(tǒng)一的一個(gè)路徑“com.alibaba.android.arouter.routes”那么這個(gè)對我們有什么影響呢?

下面分析一下這個(gè)對我們有什么影響:

酒店組件.png

用戶組件.png

對比上面兩個(gè)組件構(gòu)建后的代碼中载城,ARouter幫我們生成了幾個(gè)java文件:

ARouter$$Group$$組名

ARouter$$Providers$$組名

ARouter$$Root$$組名

如果說我們要進(jìn)行開發(fā)規(guī)范制定肌似,比如Activity的都放在act中,F(xiàn)ragment都放在fgt中诉瓦,Service都放在service中川队,然后將這些規(guī)范定義在lib_base中的一個(gè)常量ARouterPath類中進(jìn)行管理,然后再使用的時(shí)候直接使用ARouterPath.XXXX進(jìn)行調(diào)用垦搬,在實(shí)際調(diào)試中會出現(xiàn)一個(gè)效果就是如下圖:

酒店組件2.png
用戶組件2.png

可以看到ARouter幫我們生成了類名一模一樣的兩個(gè)java文件呼寸,這兩個(gè)文件分別位于不同組件的同包名下,所以當(dāng)我們進(jìn)行構(gòu)建項(xiàng)目的時(shí)候這兩個(gè)文件是會發(fā)生沖突的猴贰,其中一個(gè)會覆蓋掉另一個(gè)对雪,導(dǎo)致應(yīng)用調(diào)用異常,所以這個(gè)時(shí)候建立規(guī)則的時(shí)候建議采用組件名稱作為組名的后綴米绕,這樣可以有效的避免文件覆蓋帶來的錯(cuò)誤瑟捣。

六、MVP模式介紹

全稱Model - View - Presenter 栅干,MVP 是從經(jīng)典的模式 MVC 模式演變來的迈套,它們的基本思想有相同的地方:MVC的Controller層與MVP中的Presenter層負(fù)責(zé)邏輯的處理,Model提供數(shù)據(jù)碱鳞,View負(fù)責(zé)顯示桑李。

image.png

之前學(xué)的是后端開發(fā),第一個(gè)接觸的就是MVC模式窿给,用起來很舒爽贵白,但是做了Android開發(fā)之后使用同樣的MVC模式進(jìn)行嵌套會發(fā)現(xiàn),一切都變的不那么的美好了崩泡,因?yàn)橐晥D層Activity/Fragment既充當(dāng)了View的視圖角色禁荒,又擔(dān)任了Controller的角色,導(dǎo)致Activity/Fragment的代碼量猛增角撞,且難以閱讀和維護(hù)呛伴。

image.png

作為新的設(shè)計(jì)模式勃痴,MVP與MVC有這一個(gè)重大的區(qū)別:MVP中的View并不直接使用Model,它們之間通信是公國Presenter(MVC中的Controller)來進(jìn)行的热康,所有的交互都發(fā)生在Presenter內(nèi)部沛申,而在MVC中的View會直接從Model中讀取數(shù)據(jù)而不是通過Controller。

在MVP中褐隆,Presenter完全把Model和View進(jìn)行了分離污它,主要的程序邏輯在Presenter里實(shí)現(xiàn)。而且庶弃,Presenter與具體的View是沒有直接關(guān)聯(lián)的衫贬,而是通過定義好的接口進(jìn)行交互,從而使得在變更View時(shí)候可以保持Presenter的重用歇攻。

甚至可以在Model和View都沒有完成的時(shí)候就可以通過編寫Mock Object(即實(shí)現(xiàn)了Model和View的接口固惯,但是沒有具體的內(nèi)容)來測試Presenter的邏輯。

所以在MVP里缴守,應(yīng)用程序的邏輯主要在Presenter中實(shí)現(xiàn)葬毫,其中View是相對獨(dú)立一層。因此我們可以采用Presenter First的設(shè)計(jì)模式屡穗,就是根據(jù)需求先設(shè)計(jì)和開發(fā)Presenter贴捡。在這個(gè)過程中,View可以使很簡單村砂,能夠把信息顯示清除即可烂斋。在后面,根據(jù)具體的頁面需求再調(diào)整View的樣式础废,而對Presenter沒有任何影響汛骂。

如果UI比較復(fù)雜,而且相關(guān)的顯示邏輯還跟Model有關(guān)系评腺,就可以在View和Presenter之間放置一個(gè)Adapter帘瞭。由這個(gè)Adapter來訪問Model和View,避免兩者之間的關(guān)聯(lián)蒿讥。

在MVP模式里蝶念,View只應(yīng)該有簡單的Set/Get的方法,用戶輸入和設(shè)置頁面顯示的內(nèi)容芋绸,除此就不應(yīng)該有更多的內(nèi)容媒殉,決不允許直接訪問Model。這也是與MVC很大的不同之處侥钳。

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

1适袜、模型與視圖完全分離柄错,我們可以修改視圖而不影響模型舷夺。

2苦酱、可以更高效地使用模型,因?yàn)樗械慕换ザ及l(fā)生在一個(gè)地方给猾,Presenter內(nèi)部疫萤。

3、可以將一個(gè)Presenter用于多個(gè)視圖敢伸,而不需要改變Presenter的邏輯扯饶,這個(gè)特性非常有用因?yàn)橐晥D的變化是頻繁的。(建議僅限于同一個(gè)視圖的使用池颈,跨視圖會出現(xiàn)重寫不必要的接口方法的弊端)

4尾序、可以脫離View來進(jìn)行邏輯測試;

缺點(diǎn):

由于對視圖的渲染放在了Presenter中躯砰,所以視圖與Presenter的交互過于頻繁每币,且緊密聯(lián)系,所以一旦視圖發(fā)生變更琢歇,那么Presenter也要變更兰怠。比如說,原來呈現(xiàn)酒店詳情的視圖現(xiàn)在要呈現(xiàn)酒店周邊餐飲了李茫,那么Presenter也要變更揭保。

//TODO MVP的構(gòu)建模式,結(jié)合Dagger進(jìn)行處理等

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魄宏,一起剝皮案震驚了整個(gè)濱河市秸侣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娜庇,老刑警劉巖塔次,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異名秀,居然都是意外死亡励负,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門匕得,熙熙樓的掌柜王于貴愁眉苦臉地迎上來继榆,“玉大人,你說我怎么就攤上這事汁掠÷远郑” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵考阱,是天一觀的道長翠忠。 經(jīng)常有香客問我,道長乞榨,這世上最難降的妖魔是什么秽之? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任当娱,我火速辦了婚禮,結(jié)果婚禮上考榨,老公的妹妹穿的比我還像新娘跨细。我一直安慰自己,他們只是感情好河质,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布冀惭。 她就那樣靜靜地躺著,像睡著了一般掀鹅。 火紅的嫁衣襯著肌膚如雪散休。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天乐尊,我揣著相機(jī)與錄音溃槐,去河邊找鬼。 笑死科吭,一個(gè)胖子當(dāng)著我的面吹牛昏滴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播对人,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼谣殊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了牺弄?” 一聲冷哼從身側(cè)響起姻几,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎势告,沒想到半個(gè)月后蛇捌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咱台,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年络拌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片回溺。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡春贸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遗遵,到底是詐尸還是另有隱情萍恕,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布车要,位于F島的核電站允粤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜类垫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一绳姨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阔挠,春花似錦、人聲如沸脑蠕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谴仙。三九已至迂求,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晃跺,已是汗流浹背揩局。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掀虎,地道東北人凌盯。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像烹玉,于是被迫代替她去往敵國和親驰怎。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

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