Gradle for Android(八) 建立持續(xù)集成

持續(xù)集成【Continuous integration (CI)】是一種開發(fā)實(shí)踐则剃,它要求團(tuán)隊(duì)的開發(fā)人員定期集成他們的工作挑胸,經(jīng)常每天進(jìn)行幾次碎捺。向主倉庫的每個(gè)push由自動化構(gòu)建進(jìn)行驗(yàn)證箱歧。這種實(shí)踐有助于快速發(fā)現(xiàn)問題炎功,從而加快開發(fā)速度凤薛,提升代碼質(zhì)量姓建。偉大的Martin Fowler寫了一片文章來講解這個(gè)概念诞仓,描述最佳實(shí)踐http://martinfowler.com/articles/continuousIntegration.html

為Android設(shè)置CI有幾種選擇速兔。用的最廣泛的有Jenkins,TeamCity,Travis CI墅拭。Jenkins擁有最大的生態(tài)系統(tǒng),大約有1000個(gè)插件涣狗。它是開源的谍婉,有大量的貢獻(xiàn)者。TeamCity是JetBrains的一個(gè)產(chǎn)品屑柔,該公司同樣創(chuàng)造了IntelliJ IDEA屡萤。Travis CI相對比較新,主要用于開源項(xiàng)目掸宛。

我們將研究這些CI系統(tǒng)死陆,以及如何同Gradle協(xié)同工作。在本章末尾唧瘾,我們會提及一些Gradle技巧措译,使CI更加容易。

本章內(nèi)容有:

  • Jenkins
  • TeamCity
  • Travis CI
  • 進(jìn)一步自動化

Jenkins

Hudson最初由Sun公司于2005年發(fā)布饰序,那是Jenkins的原型领虹。這些年,它逐漸成為了Java社區(qū)最流行的CI系統(tǒng)求豫。Sun被Oracle收購不久塌衰,Oracle和Java社區(qū)關(guān)于Hudson有了沖突。在無法解決的情況下蝠嘉,社區(qū)繼續(xù)以Jenkins為名稱運(yùn)行該項(xiàng)目最疆,因?yàn)镠udson被Oracle所有。

Jenkins的強(qiáng)大在于它的插件系統(tǒng)蚤告。任何人對構(gòu)建系統(tǒng)有新功能的需求努酸,都可以創(chuàng)建插件來擴(kuò)展Jenkins的能力。這也是為什么為Android應(yīng)用或者庫配置一個(gè)自動化構(gòu)建如此簡單的原因杜恰。

配置Jenkins

如果你的電腦還沒有安裝获诈,可以在https://jenkins-ci.org下載。

在使用Jenkins之前心褐,你需要確保已安裝了所有構(gòu)建Android app和library所需的庫舔涎。構(gòu)建任何Java相關(guān)的東西,你需要安裝JDK逗爹。

你同樣需要確保安裝了Android SDK和build tools亡嫌。你不必在構(gòu)建服務(wù)器上安裝IDE,除非你打算打開項(xiàng)目。

在Java和Android SDK安裝后昼伴,你需要在Jenkins中配置它們。首先需要用瀏覽器打開Jenkin的首頁镣屹,點(diǎn)擊Manage Jenkins|Configure System圃郊,滾動到Global properties。添加ANDROID_HOME,JAVA_HOME這兩個(gè)環(huán)境變量女蜈,分別指向android SDK目錄和java目錄持舆。

圖1

你還需要安裝Gradle插件。點(diǎn)擊Manage Jenkins|Manage Plugins伪窖,打開Available標(biāo)簽逸寓,搜索Gradle。定位到Gradle插件后覆山,選擇選框竹伸,點(diǎn)擊Download now and install after restart。該插件可以創(chuàng)建Gradle相關(guān)的構(gòu)建步驟簇宽。

構(gòu)建配置

安裝了所有需要的東西后勋篓,你就可以在Jenkins中創(chuàng)建一個(gè)CI工程了。首先你需要設(shè)置VCS倉庫魏割,這樣Jenkins才知道去哪里找項(xiàng)目的源碼譬嚣。你可以基于庫的事件來設(shè)置Jenkins自動構(gòu)建Android app或者library,也可以使用觸發(fā)器或者手動構(gòu)建钞它。為了開始真正的構(gòu)建拜银,你需要調(diào)用Gradle腳本來添加一個(gè)新的構(gòu)建步驟。你可以配置Jenkins使用Gradle Wrapper遭垛。使用Gradle Wrapper不僅可以避免手動安裝Gradle尼桶,還可以確保Gradle自動更新。選擇Make gradlw executable也是非常好的耻卡。這解決了Windows系統(tǒng)創(chuàng)建的項(xiàng)目疯汁,執(zhí)行Gradle Wrapper的權(quán)限問題。

你可以為構(gòu)建步驟輸入一個(gè)描述卵酪,并可以選擇打開兩個(gè)開關(guān):info,stacktrace幌蚊。info用來打印構(gòu)建過程的信息,這在排查錯(cuò)誤時(shí)非常有用溃卡。如果構(gòu)建出現(xiàn)了異常溢豆,stacktrace開關(guān)會打印出異常的堆棧信息。有時(shí)你可能需要更加詳細(xì)的信息瘸羡,這時(shí)你可以打開full-stacktrace開關(guān)漩仙。

為了完成配置,你需要指定想要執(zhí)行的Gradle任務(wù)。首先队他,執(zhí)行clean任務(wù)卷仑,確保沒有上一個(gè)構(gòu)建的殘留輸出。其次麸折,執(zhí)行build任務(wù)锡凝,這會觸發(fā)所有構(gòu)建變體進(jìn)行構(gòu)建。Jenkins配置如下:

圖2

保存項(xiàng)目配置后垢啼,就可以構(gòu)建了窜锯。

如果你的構(gòu)建服務(wù)器安裝在64位的Linux系統(tǒng)上,可能出現(xiàn)異常java.io.IOException:Cannot run program "aapt": error=2, No such file or directory芭析。這是因?yàn)锳APT是32位的程序锚扎,在64位系統(tǒng)上運(yùn)行需要額外庫的支持∧倨簦可以通過如下命令安裝所需的庫:

$ sudo apt-get install lib32stdc++6 lib32z1

如果構(gòu)建沒有問題驾孔,它會為所有的構(gòu)建變體創(chuàng)建一個(gè)APK。你可以指定Gradle任務(wù)來分發(fā)這些APK进统。在本章末尾我們會提及自動分發(fā)助币,因?yàn)檫@是每個(gè)構(gòu)建系統(tǒng)都有的。

TeamCity

與Jenkins不同螟碎,TeamCity是一個(gè)專賣產(chǎn)品眉菱,只對開源項(xiàng)目免費(fèi)。它由JetBrains公司制作和管理掉分。TeamCity內(nèi)置支持Gradle Android構(gòu)建俭缓。

設(shè)置TeamCity

如果你還沒有安裝TeamCity,可以去JetBrains官網(wǎng)下載(https://www.jetbrains.com/teamcity)酥郭。

為使TeamCity可以構(gòu)建Android app或者library华坦,你需要確保安裝了JDK,Android SDK以及Android build tools不从。你同樣需要將ANDROID_HOME添加到電腦的環(huán)境變量中惜姐。

與Jenkins不同的是,TeamCity不需要任何插件來觸發(fā)Gradle構(gòu)建椿息,TeamCity內(nèi)置支持運(yùn)行Gradle歹袁。

構(gòu)建配置

你需要創(chuàng)建一個(gè)新的項(xiàng)目來配置Android構(gòu)建。你僅需要提供一個(gè)名稱寝优。創(chuàng)建了項(xiàng)目条舔,就可以進(jìn)行配置了。首先乏矾,你需要添加一個(gè)VCS根目錄孟抗,這樣TeamCity就可以找到項(xiàng)目的源碼了迁杨。然后你需要創(chuàng)建一個(gè)新的構(gòu)建配置。你同樣需要將VCS跟目錄綁定到構(gòu)建配置中凄硼。設(shè)置好這些铅协,你就可以添加一個(gè)新的構(gòu)建步驟。如果你點(diǎn)擊了Auto-detect build steps按鈕摊沉,TeamCity會嘗試選擇必需的構(gòu)建步驟警医,這基于項(xiàng)目的內(nèi)容。在基于Gradle的Android項(xiàng)目中坯钦,配置結(jié)果去下:

圖3

TeamCity檢測到項(xiàng)目使用了Gradle,并且Gradle Wrapper可用侈玄。你僅需要選擇Gradle構(gòu)建步驟婉刀,并將其添加到構(gòu)建配置中。如果你不需要做其他任何過多的事情序仙,這些足夠確保構(gòu)建你的Android app突颊。你可以測試配置,只需要打開項(xiàng)目預(yù)覽潘悼,點(diǎn)擊Run...按鈕律秃。

Travis CI

如果你的項(xiàng)目倉庫托管在GitHub上,你可以使用Travis CI進(jìn)行自動構(gòu)建治唤。Travis CI(https://travis-ci.org)是一個(gè)開源的托管持續(xù)集成系統(tǒng)棒动,對開源倉庫免費(fèi)。它對私有倉庫是收費(fèi)的宾添,本書只討論免費(fèi)的情況船惨。

Travis會檢測新的提交,并自動開始一個(gè)新的構(gòu)建缕陕。Travis默認(rèn)構(gòu)建所有分支粱锐,不僅僅是主分支。它同樣會自動構(gòu)建pull request扛邑。

由于Travis在內(nèi)部工作怜浅,你無法配置構(gòu)建服務(wù)器本身。你需要創(chuàng)建一個(gè)新的配置文件蔬崩,包含所有的Travis構(gòu)建你的app或者library的信息恶座。

構(gòu)建配置

如果你想使用Travis構(gòu)建你的項(xiàng)目,你首先需要登錄Travis CI舱殿,并連接到你的Github賬戶奥裸。做好了這些,你需要在設(shè)置中選擇你想構(gòu)建的項(xiàng)目沪袭。

為了配置構(gòu)建過程湾宙,Travis要求你創(chuàng)建一個(gè)名為.travis.yml的文件樟氢,包含整個(gè)配置。為了配置Android項(xiàng)目侠鳄,你需要添加一些Android特有的屬性:

language: android
android:
    components:
    # The build tools version used by your project
    - build-tools-22.0.1

    # The SDK version used to compile your project
    - android-22

    # Additional components
    - extra-android-m2repository

語言設(shè)置指定你想要運(yùn)行的構(gòu)建過程埠啃。上述情況下,你在構(gòu)建一個(gè)Android app伟恶。Android特定屬性包含構(gòu)建工具版本和Android SDK版本碴开。Travis會在執(zhí)行build任務(wù)之前下載這些東西。如果你使用了support library或者Google Play Services博秫,你需要明確指定潦牛,因?yàn)門ravis也需要去下載這些依賴。

Travis并不強(qiáng)制要求配置build tools和SDK版本挡育,但是確保它們的版本和你在build.gradle文件定義的版本一致巴碗,會使你遇到更少的問題。

如果你在windows系統(tǒng)創(chuàng)建一個(gè)Android項(xiàng)目即寒,Gradle Wrapper可能會有一些權(quán)限問題橡淆。所以,最好在運(yùn)行真正的構(gòu)建腳本之前解決它母赵。你可以添加一個(gè)預(yù)構(gòu)建步驟:

before_script:
    # Change Gradle wrapper permissions
    - chmod +x gradlew

為了開始構(gòu)建逸爵,需要將一下代碼添加到Travis的配置文件中:

# Let's build
script: ./gradlew clean build

這段代碼會運(yùn)行Gradlw wrapper,執(zhí)行cleanbuild任務(wù)凹嘲。

當(dāng)你完成了Travis構(gòu)建配置后师倔,你可以向項(xiàng)目的Github倉庫提交和推送文件。如果配置都正確周蹭,Travis會啟動構(gòu)建過程溯革,你可以在Travis網(wǎng)站上看到。一個(gè)成功的構(gòu)建如下所示:

圖4

Travis在構(gòu)建后還會發(fā)送一封郵件報(bào)告谷醉。如果你是一個(gè)經(jīng)常收到pull request的開源庫的維護(hù)人員致稀,這會非常有用。

你會很快注意到Travis有一個(gè)缺點(diǎn)俱尼,那就是速度抖单。Travis并沒有給你一臺特定機(jī)器,而是為你觸發(fā)的每個(gè)構(gòu)建啟動一個(gè)Vanilla virtual machine(VVM)遇八。也就是說矛绘,對于每個(gè)新的構(gòu)建,Travis在構(gòu)建app或者library之前刃永,需要下載安裝Android SDK和構(gòu)建工具货矮。

從好的方面看,Travis是免費(fèi)和開源的斯够,這使它對于開源項(xiàng)目非常完美囚玫。Travis會自動構(gòu)建pull request喧锦,使你及時(shí)知曉有人為你的代碼提交了補(bǔ)丁。

進(jìn)一步自動化

大多數(shù)時(shí)下的持續(xù)集成系統(tǒng)支持Gradle抓督,或是內(nèi)置支持燃少,或是通過插件支持。這意味著除了僅僅構(gòu)建你的app或者library铃在,你還可以創(chuàng)建所有的Gradle任務(wù)阵具,來進(jìn)一步自動化你的構(gòu)建。使用Gradle任務(wù)定義額外的構(gòu)建步驟定铜,而不是通過CI系統(tǒng)阳液,其優(yōu)勢在于額外的構(gòu)建步驟會變得更加便捷。在你的開發(fā)機(jī)器上運(yùn)行自定義的Gradle任務(wù)非常簡單揣炕。從另一方面看趁舀,一個(gè)自定義的Jenkins構(gòu)建步驟,可以在Jenkins沒有安裝的情況下運(yùn)行祝沸。在一個(gè)特定的CI系統(tǒng)有額外的構(gòu)建步驟使得向其他CI構(gòu)建系統(tǒng)進(jìn)行移植變得非常困難。Gradle任務(wù)也可以非常簡單的移植到不同的項(xiàng)目中越庇。在本節(jié)罩锐,我們會討論幾種方式來使用Gradle任務(wù)和插件,進(jìn)一步實(shí)現(xiàn)自動化構(gòu)建和部署app和library卤唉。

SDK管理器插件

你可能會在某個(gè)時(shí)候遇到一個(gè)問題:構(gòu)建服務(wù)器上的Android SDK不是最新的涩惑。當(dāng)你的app或者library升級SDK版本時(shí),你同樣需要在構(gòu)建服務(wù)器上安裝新的SDK氧敢。如果你有多個(gè)構(gòu)建代理蕊温,這會非常麻煩卜朗。

感謝社區(qū)的努力,有一個(gè)Gradle插件會檢查構(gòu)建所依賴的Android SDK版本是否可用痊硕,如果不可用,插件會自動下載押框。

SDK管理器插件不僅會下載構(gòu)建配置文件指定的編譯SDK岔绸,也會下載正確的build tools和platform tools版本。如果你的項(xiàng)目依賴于support library或者Google Play Services橡伞,該插件也會下載它們盒揉。

SDK管理器插件是一個(gè)開源插件,你可以在GitHub找到源碼(https://github.com/JakeWharton/sdk-manager-plugin)兑徘。

運(yùn)行測試

如果你想在構(gòu)建期間運(yùn)行單元測試(JUnit或者Robolectric)刚盈,你只需要向Gradle的執(zhí)行階段添加相應(yīng)的任務(wù)。如果你想運(yùn)行任何的功能測試挂脑,你需要模擬器來安裝app藕漱,所以你可以使用gradlew connectedAndroidTest來運(yùn)行測試.

如果你使用Jenkins欲侮,有一個(gè)名為Android Emulator Pluginhttps://wiki.jenkins-ci.org/display/JENKINS/Android+Emulator+Plugin)的插件,可以用來為每個(gè)構(gòu)建啟動一個(gè)模擬器谴分。TeamCity同樣有一個(gè)活躍的插件生態(tài)系統(tǒng)锈麸,有一個(gè)名為Android Emulator的插件可以向Jenkins插件一樣用來設(shè)置模擬器。你可以在TeamCity插件官網(wǎng)(https://confluence.jetbrains.com/display/TW/TeamCity+Plugins)找到它牺蹄。

Travis CI也可以啟動一個(gè)模擬器忘伞,但這是一個(gè)實(shí)驗(yàn)功能。如果你使用它沙兰,將下面的代碼片段添加到你的.travis.yml配置文件中:

# Emulator Management: Create, Start and Wait
before_script:
    - echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
    - emulator -avd test -no-skin -no-audio -no-window &
    - android-wait-for-emulator
    - adb shell input keyevent 82 &

android-wait-for-emulator指令告知Travis等待模擬器的啟動氓奈。模擬器啟動后,adb shell input keyevent 82 &會執(zhí)行鼎天,從而解鎖屏幕舀奶。之后,就可以運(yùn)行測試了斋射。

持續(xù)部署

為了幫助開發(fā)者自動部署Android app育勺,Google發(fā)布了Google Play Developer API,一個(gè)以編程方式將APK發(fā)布到Google Play的API(https://developers.google.com/android-publisher)罗岖。這個(gè)API使你不必再打開瀏覽器涧至,登錄Google Play,然后使用web接口上傳APK桑包。你不必再基于Google Play Developer API創(chuàng)建自己的發(fā)布腳本南蓬,而只需要在成功構(gòu)建之后,在構(gòu)建系統(tǒng)中使用眾多插件中的一個(gè)來向Google Play推送APK哑了。

Jenkins有一個(gè)名為Google Play Android Publisherhttps://wiki.jenkins-ci.org/display/JENKINS/Google+Play+Android+Publisher+Plugin)的插件可以為你做這些赘方。然而,一個(gè)更好的選擇是使用Gradle插件弱左,這樣你就可以在任何設(shè)備窄陡,任何類型的持續(xù)集成系統(tǒng)中運(yùn)行發(fā)布任務(wù)了。Android社區(qū)的某些人創(chuàng)建了基于Google Play Developer API的Gradle任務(wù)來幫助配置整個(gè)發(fā)布過程拆火。你可以在GitHub(https://github.com/Triple-T/gradle-play-publisher)找到Gradle插件Gradle Play Publisher的源碼泳梆。它也發(fā)布在了Maven Center和JCenter上。

為了使用該插件榜掌,需要在頂級構(gòu)建文件中添加如下語句:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.github.triplet.gradle:play-publisher:1.0.4'
    }
}

然后在你的Android模塊的配置文件中應(yīng)用這個(gè)插件:

apply plugin: 'play'

應(yīng)用了Gradle Play Publisher插件后优妙,你會有幾個(gè)新的可用任務(wù):

  • publishApkRelease上傳APK和最近的變更
  • publishListingRelease上傳描述和圖片
  • publishRelease上傳所有東西

如果你有不同的構(gòu)建變體,你也可以運(yùn)行特定變體的版本憎账,比如publishApkFreeReleasepublishApkPaidRelease套硼。

為了訪問Google Play Developer API,你需要設(shè)置一個(gè)服務(wù)賬戶胞皱。這個(gè)設(shè)置超出了本書的范圍邪意,但如果你想使用Gradle Play Publisher九妈,這是必需的。你可以在https://developers.google.com/android-publisher/getting_started得到幫助雾鬼。

在你創(chuàng)建了服務(wù)賬戶后萌朱,你可以在構(gòu)建配置文件中添加證書:

play {
    serviceAccountEmail = 'serviceaccount'
    pk12File = file('key.p12')
}

play塊中包含Gradle Play Publisher插件特有的屬性。除了服務(wù)賬號證書策菜,你還可以指定APK的發(fā)布途徑:

play {
    track = 'production'
}

默認(rèn)的途徑是alpha晶疼,你可以修改為beta或者product

Beta分發(fā)

有很多Android app的beta測試又憨,比如Google Play商店的bata途徑翠霍。另一個(gè)是Crashlyticshttps://crashlytics.com),與Gradle有很好的集成蠢莺。Crashlytics的團(tuán)隊(duì)創(chuàng)建了這個(gè)自定義的插件寒匙,不僅可以創(chuàng)建新的Gradle任務(wù)來向他們的平臺發(fā)布構(gòu)建,還可以與Android插件任務(wù)掛鉤來操作ProGuard映射躏将。

你可以按照網(wǎng)站的步驟來使用Crashlytics锄弱。設(shè)置好后,它就會與你的構(gòu)建掛鉤祸憋。Crashlytics插件暴露了一個(gè)名為crashlyticsUploadDistributionInternal的任務(wù)会宪,可以用來將APK上傳到Crashlytics。為了推送一個(gè)新的app版本夺衍,你首先需要使用build或者assemble任務(wù)來進(jìn)行構(gòu)建。APK準(zhǔn)備好后喜命,你可以使用crashlyticsUploadDistributionInternal任務(wù)將它上傳到Crashlytics沟沙。Crashlytics插件為每個(gè)構(gòu)建變體創(chuàng)建了一個(gè)上傳任務(wù)。

自定義Gradle插件使開發(fā)者們可以很容易地使用Crashlytics壁榕,也使你很容易將你的測試構(gòu)建上傳到Crashlytics矛紫,因?yàn)槟阒恍枰跇?gòu)建構(gòu)成中執(zhí)行一個(gè)額外的任務(wù)。這是一個(gè)恰當(dāng)使用Gradle強(qiáng)大之處牌里,以及一個(gè)好的Gradle插件使編程變得簡單的的很好的例子颊咬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市牡辽,隨后出現(xiàn)的幾起案子喳篇,更是在濱河造成了極大的恐慌,老刑警劉巖态辛,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麸澜,死亡現(xiàn)場離奇詭異,居然都是意外死亡奏黑,警方通過查閱死者的電腦和手機(jī)炊邦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門编矾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人馁害,你說我怎么就攤上這事窄俏。” “怎么了碘菜?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵凹蜈,是天一觀的道長。 經(jīng)常有香客問我炉媒,道長踪区,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任吊骤,我火速辦了婚禮缎岗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘白粉。我一直安慰自己传泊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布鸭巴。 她就那樣靜靜地躺著眷细,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鹃祖。 梳的紋絲不亂的頭發(fā)上溪椎,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機(jī)與錄音恬口,去河邊找鬼校读。 笑死,一個(gè)胖子當(dāng)著我的面吹牛祖能,可吹牛的內(nèi)容都是我干的歉秫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼养铸,長吁一口氣:“原來是場噩夢啊……” “哼雁芙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钞螟,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤兔甘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后鳞滨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裂明,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了闽晦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扳碍。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖仙蛉,靈堂內(nèi)的尸體忽然破棺而出笋敞,到底是詐尸還是另有隱情,我是刑警寧澤荠瘪,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布夯巷,位于F島的核電站,受9級特大地震影響哀墓,放射性物質(zhì)發(fā)生泄漏趁餐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一篮绰、第九天 我趴在偏房一處隱蔽的房頂上張望后雷。 院中可真熱鬧,春花似錦吠各、人聲如沸臀突。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽候学。三九已至,卻和暖如春纵散,著一層夾襖步出監(jiān)牢的瞬間梳码,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工伍掀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掰茶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓硕盹,卻偏偏與公主長得像符匾,于是被迫代替她去往敵國和親叨咖。 傳聞我的和親對象是個(gè)殘疾皇子瘩例,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

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