Android模塊化開發(fā)與ARouter框架

在App開發(fā)的初期鳖悠,代碼量不大假瞬,業(yè)務(wù)量比較少环肘,一個(gè)App作為一個(gè)單獨(dú)的模塊進(jìn)行開發(fā)燎含,往往問題不大锚赤。但隨著業(yè)務(wù)的增多馒胆,代碼變的越來越復(fù)雜狭郑,每個(gè)模塊之間的代碼耦合變得越來越嚴(yán)重亚茬,結(jié)構(gòu)越來越臃腫偏陪,修改一處代碼要編譯整個(gè)工程抢呆,導(dǎo)致非常耗時(shí),這時(shí)候解耦問題急需解決笛谦。

同時(shí)抱虐,如果公司有多個(gè)終端設(shè)備的App,而且有塊功能是通用的(比如說下單功能)饥脑,那么通用的這一塊功能被復(fù)制集成到不同App里恳邀,就顯得很重復(fù),而且維護(hù)時(shí)要修改多套代碼灶轰,嚴(yán)重影響開發(fā)效率谣沸,因此模塊化開發(fā)就很有必要。

App模塊化的目標(biāo)是告別結(jié)構(gòu)臃腫笋颤,讓各個(gè)業(yè)務(wù)變得相對(duì)獨(dú)立乳附,業(yè)務(wù)模塊在組件模式下可以獨(dú)立開發(fā),而在集成模式下又可以變?yōu)橐蕾嚢傻健癮pp殼工程”中伴澄,組成一個(gè)完整功能的APP赋除。

一、模塊化開發(fā)的好處

  • 公用功能非凌,不用重復(fù)開發(fā)举农、修改,代碼復(fù)用性更強(qiáng)
  • 獨(dú)立運(yùn)行敞嗡,提高編譯速度颁糟,也就提高了開發(fā)效率
  • 更利于團(tuán)隊(duì)開發(fā)祭犯,不同的人可以獨(dú)立負(fù)責(zé)不同的模塊
  • 獨(dú)立模塊可以采用不同的技術(shù)架構(gòu),嘗試新的技術(shù)方案滚停,比如采用新的網(wǎng)絡(luò)框架沃粗,甚至換成Kotlin來開發(fā)App

二、模塊化要解決的問題

  • 模塊間頁面跳轉(zhuǎn)(路由)键畴;
  • 模塊間事件通信最盅;
  • 模塊間服務(wù)調(diào)用;
  • 模塊的獨(dú)立運(yùn)行起惕;
  • 模塊間頁面跳轉(zhuǎn)路由攔截(登錄)

三涡贱、ARouter路由框架

以上模塊化需要要解決的問題,2017年阿里開源的路由框架ARouter都有提供解決方案惹想。
官方對(duì)這個(gè)框架的定義是:一個(gè)用于幫助 Android App 進(jìn)行組件化改造的框架 —— 支持模塊間的路由问词、通信、解耦嘀粱。
ARouter提供的功能有:

  • 支持直接解析標(biāo)準(zhǔn)URL進(jìn)行跳轉(zhuǎn)激挪,并自動(dòng)注入?yún)?shù)到目標(biāo)頁面中
  • 支持多模塊工程使用
  • 支持添加多個(gè)攔截器,自定義攔截順序
  • 支持依賴注入锋叨,可單獨(dú)作為依賴注入框架使用
  • 支持InstantRun
  • 支持MultiDex(Google方案)
  • 映射關(guān)系按組分類垄分、多級(jí)管理,按需初始化
  • 支持用戶指定全局降級(jí)與局部降級(jí)策略
  • 頁面娃磺、攔截器薄湿、服務(wù)等組件均自動(dòng)注冊(cè)到框架
  • 支持多種方式配置轉(zhuǎn)場(chǎng)動(dòng)畫
  • 支持獲取Fragment
  • 完全支持Kotlin以及混編(配置見文末 其他#5)
  • 支持第三方 App 加固(使用 arouter-register 實(shí)現(xiàn)自動(dòng)注冊(cè))
  • 支持生成路由文檔
  • 提供 IDE 插件便捷的關(guān)聯(lián)路徑和目標(biāo)類

附上ARouter官網(wǎng)地址:ARouter

其中,關(guān)于路由方面偷卧,Google提供的原生路由主要是通過Intent豺瘤,Intent可以分成顯示和隱式兩種。顯示的方案會(huì)導(dǎo)致類之間的直接依賴問題听诸,耦合嚴(yán)重;隱式Intent需要在配置清單中統(tǒng)一聲明坐求,首先有個(gè)暴露的問題,另外在多模塊開發(fā)中協(xié)作也比較困難蛇更。除此之外瞻赶,使用原生的路由方案會(huì)出現(xiàn)跳轉(zhuǎn)過程無法控制的問題,因?yàn)橐坏┦褂昧藄tartActivity()就無法插手其中任何環(huán)節(jié)了派任,只能交給系統(tǒng)管理砸逊,這就導(dǎo)致了在跳轉(zhuǎn)失敗的情況下無法降級(jí),而是會(huì)直接拋出運(yùn)營(yíng)級(jí)的異常掌逛。

// Intent顯式啟動(dòng)Activity
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
// Intent隱式啟動(dòng)Activity
Intent intent = new Intent("com.example.activity.ACTION_START");
startActivity(intent);

如果使用ARouter师逸,可以在跳轉(zhuǎn)過程中進(jìn)行攔截,出現(xiàn)錯(cuò)誤時(shí)可以實(shí)現(xiàn)降級(jí)策略. 比如跳轉(zhuǎn)頁面不存在不是直接crash而是可以跳轉(zhuǎn)到一個(gè)指定的默認(rèn)頁面豆混。

四篓像、用ARouter進(jìn)行模塊化開發(fā)

接下來动知,將會(huì)用一個(gè)demo介紹如何用ARouter進(jìn)行模塊化開發(fā),demo模塊化的整體架構(gòu)如下:

  • app:項(xiàng)目的宿主模塊员辩,僅僅是一個(gè)空殼盒粮,依賴于其他模塊,成為項(xiàng)目架構(gòu)的入口
  • baselibrary:項(xiàng)目的基類庫奠滑,每個(gè)子模塊都依賴共享公用的類和資源丹皱,防止公用的功能在不同的模塊中有多個(gè)實(shí)現(xiàn)方式
  • module_route:集中管理所有模塊的route
  • module_main:閃屏頁,登錄頁宋税,主頁等
  • module_home:首頁模塊
  • module_mine:我的模塊
  • module_video:視頻模塊


    module

五摊崭、依賴模式與獨(dú)立運(yùn)行模式切換

在項(xiàng)目開發(fā)中,各個(gè)模塊可以同時(shí)開發(fā)杰赛,獨(dú)立運(yùn)行而不必依賴于宿主app呢簸,也就是每個(gè)module是一個(gè)獨(dú)立的App,項(xiàng)目發(fā)布的時(shí)候依賴到宿主app中乏屯。各業(yè)務(wù)模塊之間不允許存在相互依賴關(guān)系根时,但是需要依賴基類庫。單一模塊生成的apk體積也小瓶珊,編譯時(shí)間也快啸箫,開發(fā)效率會(huì)高很多,同時(shí)也可以獨(dú)立測(cè)試伞芹。要實(shí)現(xiàn)這樣的效果需要對(duì)項(xiàng)目做一些配置。

1蝉娜、gradle.properties配置

在項(xiàng)目gradle.properties中需要設(shè)置一個(gè)開關(guān)唱较,用來控制module的編譯,如下:

isModule=false

當(dāng)isModule為false作為依賴庫召川,只能以宿主app啟動(dòng)項(xiàng)目南缓,選擇運(yùn)行模塊時(shí)其他module前都是紅色的X,表示無法運(yùn)行


依賴宿主模式

當(dāng)isModule為true的時(shí)候作為單獨(dú)的模塊進(jìn)行運(yùn)行荧呐,選擇其中一個(gè)module可以直接運(yùn)行


獨(dú)立運(yùn)行模式

2汉形、清單文件配置

module清單文件需要配置兩個(gè),一個(gè)作為獨(dú)立項(xiàng)目的清單文件倍阐,一個(gè)作為庫的清單文件概疆,以module_main模塊為例:


清單文件

buildApp作為依賴庫的清單文件,和獨(dú)立項(xiàng)目的清單文件buildModule區(qū)別是依賴庫的清單文件Application中沒有配置入口的Activity峰搪,其他都一樣

3岔冀、gradle配置

gradle配置

4、宿主app配置

宿主app配置

六概耻、ARouter功能詳解

1使套、添加依賴和配置

android {
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [moduleName: project.getName()]
            }
        }
    }
}

dependencies {
    // 替換成最新版本, 需要注意的是api
    // 要與compiler匹配使用罐呼,均使用最新版可以保證兼容
    compile 'com.alibaba:arouter-api:x.x.x'
    annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
    ...
}

注意,arouter-api:1.3.1侦高、arouter-compiler:1.1.4配置是

arguments = [moduleName: project.getName()]

arouter-api:1.4.1嫉柴、arouter-compiler:1.2.2配置是

arguments = [AROUTER_MODULE_NAME: project.getName()]

2、添加注解

// 在支持路由的頁面上添加注解(必選)
// 這里的路徑需要注意的是至少需要有兩級(jí)奉呛,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}

在我的demo中计螺,各模塊的route地址都統(tǒng)一放在module_route中集中管理,其他module都需要依賴module_route侧馅,同時(shí)不同模塊的route有單獨(dú)的RoutePath類危尿。如圖:


module_route
@Route(path = MainRoutePath.LOGIN_ACTIVITY)
public class LoginActivity extends BaseActivity {
    ...
}
public class MainRoutePath {

    private static final String PREFIX = "/main/";

    public static final String MAIN_ACTIVITY = PREFIX+"MainActivity";

    public static final String LOGIN_ACTIVITY = PREFIX+"LoginActivity";

}

  • 問題1:為什么要把route地址寫在一個(gè)常量類里?
//聲明的地方
@Route(path = "/test/activity")

//使用的地方
ARouter.getInstance().build("/test/activity").navigation();

聲明的地方和使用的地方可以是處于不同的module馁痴,這種寫法各module不需要相互依賴谊娇,貌似很好,耦合度很低罗晕。但這只是表面上看代碼沒有了耦合度济欢,但他們的耦合關(guān)系還在,試想一下小渊,聲明的地方哪天把route地址改了法褥,使用的地方完全“無感”,只有等到真正運(yùn)行時(shí)才能發(fā)現(xiàn)出錯(cuò)了酬屉,這種寫法風(fēng)險(xiǎn)很大半等,而且不容易提前發(fā)現(xiàn)。如果聲明的地方和使用的地方route都用一個(gè)常量來表示呐萨,就能很好的避免這種風(fēng)險(xiǎn)杀饵。

  • 問題2:為什么不同模塊的route有單獨(dú)的RoutePath類
    因?yàn)橐粋€(gè)App一般頁面都比較多,如果所有route都用一個(gè)RoutePath類來裝谬擦,那這個(gè)類將會(huì)很大切距,且不同模塊開發(fā)人員都需要去改這個(gè)類,容易產(chǎn)生混亂惨远。如果不同模塊的route有單獨(dú)的RoutePath類谜悟,不同模塊的開發(fā)人員只去改對(duì)應(yīng)的類,代碼會(huì)更好管理北秽。
  • 問題3:為什么要單獨(dú)建一個(gè)module_route葡幸,僅僅只配置route,為什么不把RoutePath類放在baselibrary里羡儿?
    baselibrary一般是一些通用的基礎(chǔ)功能或通用配置礼患,正常情況下應(yīng)只能讓少數(shù)的有架構(gòu)層次的開發(fā)人員去改動(dòng),所以應(yīng)該做權(quán)限保護(hù),如果把RoutePath放在baselibrary里缅叠,相當(dāng)于baselibrary對(duì)所有開發(fā)人員都是開發(fā)的悄泥。
  • 問題4:配置route地址時(shí),有什么講究肤粱?
    如上MainRoutePath中弹囚,我的route地址配置規(guī)則采用的是: 前綴 + Activity類名,前綴一般用module名字领曼。根據(jù)官方文檔說明
    1鸥鹉、SDK中針對(duì)所有的路徑(/test/1 /test/2)進(jìn)行分組,分組只有在分組中的某一個(gè)路徑第一次被訪問的時(shí)候庶骄,該分組才會(huì)被初始化毁渗;
    2、可以通過 @Route 注解主動(dòng)指定分組单刁,否則使用路徑中第一段字符串(/*/)作為分組灸异。
    意思是用分組可以按需加載,提高性能羔飞,當(dāng)沒有主動(dòng)分組時(shí)肺樟,ARouter用第一段字符串作為分組。所以我的前綴就是分組名逻淌,不用再去主動(dòng)指定分組么伯。

3、初始化SDK

if (isDebug()) {           // 這兩行必須寫在init之前卡儒,否則這些配置在init過程中將無效
    ARouter.openLog();     // 打印日志
    ARouter.openDebug();   // 開啟調(diào)試模式(如果在InstantRun模式下運(yùn)行田柔,必須開啟調(diào)試模式!線上版本需要關(guān)閉,否則有安全風(fēng)險(xiǎn))
}
ARouter.init(mApplication); // 盡可能早骨望,推薦在Application中初始化

4凯楔、發(fā)起路由操作

// 1. 簡(jiǎn)單的跳轉(zhuǎn)
ARouter.getInstance().build(MainRoutePath.MAIN_ACTIVITY).navigation();

// 2. 跳轉(zhuǎn)并攜帶參數(shù)
ARouter.getInstance().build(MainRoutePath.MAIN_ACTIVITY)
                            .withString("name", name)
                            .withInt("age", 28)
                            .navigation();

5、目標(biāo)頁面接收參數(shù)

@Route(path = MainRoutePath.MAIN_ACTIVITY)
public class MainActivity extends BaseActivity {

    /**
     * 接收參數(shù)
     */
    @Autowired(name = "name")
    public String name;
    @Autowired(name = "age")
    public int age;
    ...
}

6锦募、聲明攔截器(攔截跳轉(zhuǎn)過程,面向切面編程)

攔截都是全局性的邻遏,因此一般寫在baselibrary里糠亩,如權(quán)限校驗(yàn)的攔截器。攔截器會(huì)在跳轉(zhuǎn)之間執(zhí)行准验,多個(gè)攔截器會(huì)按優(yōu)先級(jí)順序依次執(zhí)行


AuthInterceptor

但是需要注意的是赎线,每次所有的跳轉(zhuǎn)都會(huì)執(zhí)行攔截器操作,ARouter提供了greenChannel()方法進(jìn)行跳轉(zhuǎn)過去一切攔截器糊饱,在不需要攔截器的地方跳轉(zhuǎn)的時(shí)候加上即可垂寥。

 //greenChannel表示跳過攔截器驗(yàn)證
 ARouter.getInstance().build(MainRoutePath.LOGIN_ACTIVITY).greenChannel().navigation();

7、降級(jí)策略

ARouter提供的降級(jí)策略主要有兩種方式,一種是通過回調(diào)的方式滞项;一種是提供服務(wù)接口的方式狭归。我們分別來看看兩種方式的使用方法:

  • 一、單獨(dú)降級(jí)-回調(diào)的方式
    這種方式在跳轉(zhuǎn)失敗的時(shí)候會(huì)回調(diào)NavCallback接口的onLost方法文判。
ARouter.getInstance().build(MainRoutePath.MAIN_ACTIVITY).navigation(this, new NavCallback() {
     @Override
     public void onFound(Postcard postcard) {
          Log.d("ARouter", "找到了");
     }

     @Override
     public void onLost(Postcard postcard) {
          Log.d("ARouter", "找不到了");
     }

     @Override
     public void onArrival(Postcard postcard) {
          Log.d("ARouter", "跳轉(zhuǎn)完了");
     }

     @Override
      public void onInterrupt(Postcard postcard) {
           Log.d("ARouter", "被攔截了");
      }
});

回調(diào)接口,對(duì)于降級(jí)策略主要實(shí)現(xiàn)感興趣的onLost方法即可过椎。

  • 二、全局降級(jí)-服務(wù)接口的方式
    這種方式很簡(jiǎn)單戏仓,主要處理邏輯在內(nèi)部疚宇,暴露的接口很友好。
//跳轉(zhuǎn)目標(biāo)頁面不存在赏殃,觸發(fā)降級(jí)策略 避免crash
ARouter.getInstance().build("/test/test").navigation();

這種降級(jí)策略主要是實(shí)現(xiàn)服務(wù)接口DegradeService敷待,就一個(gè)方法就是onLost,和上面的類似仁热。

//要用ARouter跳轉(zhuǎn)才能攔截到榜揖,用Intent隱式或顯示跳轉(zhuǎn)無法攔截,出錯(cuò)還是會(huì)crash
@Route(path = RoutePath.DEGRADE)
public class DegradeServiceImpl implements DegradeService {
    @Override
    public void onLost(Context context, Postcard postcard) {
        ARouter.getInstance().build(RoutePath.DEGRADE_TIP).greenChannel().navigation();
    }

    @Override
    public void init(Context context) {

    }
}

全局降級(jí)-服務(wù)接口也應(yīng)該寫在baselibrary里

8股耽、使用 IDE 插件導(dǎo)航到目標(biāo)類

在 Android Studio 插件市場(chǎng)中搜索 ARouter Helper, 或者直接下載文檔上方 最新版本 中列出的 arouter-idea-plugin zip 安裝包手動(dòng)安裝根盒,安裝后 插件無任何設(shè)置,可以在跳轉(zhuǎn)代碼的行首找到一個(gè)圖標(biāo) 點(diǎn)擊該圖標(biāo)物蝙,即可跳轉(zhuǎn)到標(biāo)識(shí)了代碼中路徑的目標(biāo)類炎滞,如圖:

ARouter Helper安裝一

ARouter Helper安裝二

跳轉(zhuǎn)快捷 圖標(biāo)

9、生成路由文檔

// 更新 build.gradle, 添加參數(shù) AROUTER_GENERATE_DOC = enable
// 生成的文檔路徑 : build/generated/source/apt/(debug or release)/com/alibaba/android/arouter/docs/arouter-map-of-${moduleName}.json

arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"]
路由文檔

七诬乞、Android Butterknife在library組件化模塊中的使用問題

1册赛、問題

當(dāng)項(xiàng)目中有多module時(shí),在使用Butterknife的時(shí)候會(huì)發(fā)現(xiàn)在library模塊中使用會(huì)出問題震嫉。當(dāng)library模塊中的頁面通過butterknife找id的時(shí)候森瘪,就會(huì)報(bào)錯(cuò),提示@BindView的屬性必須是一個(gè)常數(shù)票堵,也就是說library module編譯的時(shí)候扼睬,R文件中所有的數(shù)據(jù)并沒有被加上final,也就是R文件中的數(shù)據(jù)并非常量悴势。

2窗宇、解決步驟

  • I 首先在項(xiàng)目的總build.gradle中添加classpath
classpath 'com.jakewharton:butterknife-gradle-plugin:8.2.1'
build.gradle
  • II 在library中build.gradle中引入插件
apply plugin: 'com.jakewharton.butterknife'
library build.gradle
  • III 在library中build.gradle中dependencies添加依賴
compile "com.jakewharton:butterknife:8.5.1"
annotationProcessor "com.jakewharton:butterknife-compiler:8.5.1"

3、butterknife在library activity中的使用和注意事項(xiàng)

1特纤、用R2代替R findviewid

   @BindView(R2.id.textView)
    TextView textView;
    @BindView(R2.id.button1)
    Button button1;
    @BindView(R2.id.image)
    ImageView image;

2军俊、在click方法中同樣使用R2,但是找id的時(shí)候使用R

 @OnClick({R2.id.textView, R2.id.button1, R2.id.button2, R2.id.button3, R2.id.image})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.textView:
                break;
            case R.id.button1:
                break;
            case R.id.image:
                break;
        }
    }

3捧存、特別注意library中switch-case的使用粪躬,在library中是不能使用switch- case 找id的担败,解決方法就是用if-else代替

@OnClick({R2.id.textView, R2.id.button1, R2.id.button2, R2.id.button3, R2.id.image})
    public void onViewClicked(View view) {
        int i = view.getId();
        if (i == R.id.textView) {

        } else if (i == R.id.button1) {

        } else if (i == R.id.image) {

        }
    }

八、 Demo地址

  • ARouter的其他詳細(xì)功能镰官,可閱讀官方文檔:ARouter
  • 最后附上我的Demo地址:ARouter Demo

最后給大家送波福利

阿里云折扣快速入口

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末提前,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子朋魔,更是在濱河造成了極大的恐慌岖研,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件警检,死亡現(xiàn)場(chǎng)離奇詭異孙援,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扇雕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門拓售,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人镶奉,你說我怎么就攤上這事础淤。” “怎么了哨苛?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵鸽凶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我建峭,道長(zhǎng)玻侥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任亿蒸,我火速辦了婚禮凑兰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘边锁。我一直安慰自己姑食,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布茅坛。 她就那樣靜靜地躺著音半,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贡蓖。 梳的紋絲不亂的頭發(fā)上祟剔,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音摩梧,去河邊找鬼。 笑死宣旱,一個(gè)胖子當(dāng)著我的面吹牛仅父,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼笙纤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼耗溜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起省容,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤抖拴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后腥椒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阿宅,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年笼蛛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洒放。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滨砍,死狀恐怖往湿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惋戏,我是刑警寧澤领追,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站响逢,受9級(jí)特大地震影響绒窑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜龄句,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一回论、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧分歇,春花似錦傀蓉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缚甩,卻和暖如春谱净,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背擅威。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工壕探, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郊丛。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓李请,卻偏偏與公主長(zhǎng)得像瞧筛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子导盅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348