[AS3.0.1]Gradle代碼整合優(yōu)化

1.build.gradle講解

首先我將一個(gè)demo項(xiàng)目中的一份build.gradle拿出來講解下

apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.butterknife'

android {
    //簽名配置
    signingConfigs {
        //簽名Name
        config {
            //簽名別名
            keyAlias 'gjn'
            //簽名別名密碼
            keyPassword '11223344'
            //簽名文件位置
            storeFile file('D:/project/MyDemo/gjnKey.jks')
            //簽名密碼
            storePassword '11223344'
        }
    }
    //開發(fā)環(huán)境版本號(hào)
    compileSdkVersion 26
    //默認(rèn)配置
    defaultConfig {
        //Id
        applicationId "com.gjn.mydemo"
        //最小支持版本號(hào)
        minSdkVersion 19
        //運(yùn)行版本號(hào)
        targetSdkVersion 25
        //appCode
        versionCode 1
        //app版本號(hào)
        versionName "1.0"
        //測(cè)試相關(guān)
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    //Build類型 默認(rèn)有release和debug兩個(gè)版本
    buildTypes {
        release {
            //是否開始混淆
            minifyEnabled false
            //混淆文件路徑
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //打包時(shí)候調(diào)用的簽名
            signingConfig signingConfigs.config
            //在BuildConfig生成一個(gè)String類型的Host=release_Host
            //即 public static final String Host = "release_Host";
            buildConfigField "String", "Host", "\"release_Host\""
            //編譯之后會(huì)在res文件中的string.xml中加入一個(gè)string類型的app_name1=myMode
            //即 <string name="app_name1">myMode</string>
            resValue "string", "app_name1", "myMode"
            //修改build之后的app名稱
            //這邊編譯出來的名字是 release_1.0.apk
            //這個(gè)寫法是Android Studio 3.0之后的方法
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "${variant.name}_${variant.versionName}.apk"
                }
            }
        }
        debug {
            //為Id添加后綴 這邊生成新的Id為com.gjn.mydemo.debug
            applicationIdSuffix ".debug"
            //這邊下面和上面是一樣

            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("String", "Host", "\"debug_Host\"")
            resValue("string", "app_name1", "myModedebug")

            //占位符 替換AndroidManifest.xml 中的${test_key}字符
            //AndroidManifest.xml中的源代碼為
            //<meta-data android:name="TEST_KEY" android:value="${test_key}"/>
            //替換之后
            //<meta-data android:name="TEST_KEY" android:value="debug_key"/>
            manifestPlaceholders = ["test_key": "debug_key"]
        }
    }
    //多版本
    productFlavors{
        //dev版本
        dev{
            manifestPlaceholders = ["test_key": "release_key"]
        }
        //free版本
        free{
            //這邊在提下敌厘,由于free也會(huì)有release和debug兩個(gè)版本
            //release的Id為com.gjn.mydemo.free
            //debug的Id為com.gjn.mydemo.free.debug
            applicationIdSuffix ".free"
            manifestPlaceholders = ["test_key": "free_key"]
        }
    }
    //遍歷了全部版本
    productFlavors.all{
        //設(shè)置統(tǒng)一Code Android Studio 3.0之后需要設(shè)置這個(gè)屬性 不然構(gòu)建多版本的時(shí)候會(huì)報(bào)錯(cuò)
        flavorDimensions("versionCode")
    }
}
//導(dǎo)入第三方之類的jar aar 等 就不說了
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation 'com.jakewharton:butterknife:8.7.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0'
    implementation 'com.github.bumptech.glide:glide:3.7.0'
    implementation 'com.google.code.gson:gson:2.8.0'
    implementation 'com.squareup.okhttp3:okhttp:3.8.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.1.1'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
}

我將大部分內(nèi)容都設(shè)置了備注,可以看到很多常用的屬性設(shè)置朽合。還有許多其他的俱两,后續(xù)在補(bǔ)充


2.Groovy講解

這邊我稍微對(duì)Groovy的語法和邏輯說一點(diǎn)!
首先說下
關(guān)于注釋之類和java是一樣的

  • 字符串

在java中就只有一種"android"

而Groovy中有
單行'android', "android"
多行 '''android''', """android""
還有/.../曹步,${...}

  • 集合(List宪彩,Map)

List

創(chuàng)建和初始化

def list = [1,'hello',false]

這邊不需要List中的每個(gè)類型都相同,當(dāng)然Map也一樣讲婚。

使用

    println list[1]     //輸出 hello
    println list[-1]    //輸出 false
    list[1] = 5         //5 替換 hello
    list[0] = "android" //android 替換 1
    list << "gjn"       //追加 gjn
    list.each { l ->    //遍歷整個(gè)list
        println l       //每次輸出一項(xiàng)
    }

結(jié)果

hello
false
android
5
false
gjn

Map

創(chuàng)建和初始化

def map = [1:'hello',android:233,b:false]

使用

    println map[1]      //輸出 hello
    println map.b       //輸出 false
    map << [2:33]       //追加 2:33
    map.each { k,v->    //遍歷map
        println k+":"+v
    }

結(jié)果

hello
false
1:hello
android:233
b:false
2:33
  • 數(shù)組

關(guān)于數(shù)組
groovy 其實(shí)沒有嚴(yán)格區(qū)分?jǐn)?shù)組和集合尿孔,數(shù)組的定義和使用方法跟集合一樣,只是你需要強(qiáng)制聲明為數(shù)組筹麸,否則默認(rèn)為集合活合。

創(chuàng)建和初始化

String[] arrString = ['hello',"android","""groovy
=============="""]
def arrNum = [1,2,3] as int[]

直接String[]和Java一樣是創(chuàng)建數(shù)組
as int[]是把a(bǔ)rrNum設(shè)置為數(shù)組,不然就會(huì)變成集合

使用

    arrString.each {str->
        println str
    }
    arrNum.each {num->
        println num
    }

結(jié)果

hello
android
groovy
==============
1
2
3
  • 遍歷
    groovy中的遍歷有2個(gè)each{...}all{...}
    遍歷在上面的數(shù)組和集合都使用了物赶,大體上都知道使用了白指。
    拿第一個(gè)說下each就是Java中的foreach
    list.each { l ->    //遍歷整個(gè)list
        println l       //每次輸出一項(xiàng)
    }

其實(shí)就等于Java中的

    List<String> list = new ArrayList<>();
    for(String l : list){
        System.out.println(l);
    }

all和each的使用是一樣的,區(qū)別我查了下酵紫,有提到是each使用的是迭代告嘲,不能實(shí)時(shí)修改值错维,all使用的是拾取對(duì)象,可以修改值橄唬。好比ArrayList和CopyOnWriteArrayList的區(qū)別吧赋焕!
我也不太確定,只是在 Android Gradle 3.0.0-alpha2 plugin, Cannot set the value of read-only property 'outputFile'
中有看到仰楚。

  • 方法簡(jiǎn)化使用

groovy的一個(gè)特性
groovy 定義方法時(shí)可以不聲明返回類型和參數(shù)類型隆判,也可以不需要 return 語句,最后一行代碼默認(rèn)就是返回值缸血。使用的時(shí)候也可以不需要添加括號(hào)蜜氨。
使用1

def add(a,b){
    a+b
}

def str = add 1,2
println str    //結(jié)果為3

結(jié)果1

3

這邊我們就能發(fā)現(xiàn)很多在build.gradle中的參數(shù)的真實(shí)代碼
例如
compileSdkVersion 26 就是 compileSdkVersion(26)
applicationId "com.gjn.mydemo" 就是 applicationId("com.gjn.mydemo")
等等

使用2

def getmap(Map map){
    map.each {
        println it.key + ":" + it.value
    }
}

def map = [1:"hello",2:true]
getmap map

def map2 = [add:'groovy']
getmap map2

getmap add:'groovy test'

結(jié)果2

1:hello
2:true
add:groovy
add:groovy test

這次使用我們就發(fā)現(xiàn)了一個(gè)getmap add:'groovy test'和build.gradle中的apply plugin: 'com.android.application'很像有沒有。
如果按照我們上面的寫法捎泻,那么原本的apply方法就是

apply plugin: 'com.android.application'
等于
def map = [plugin: 'com.android.application']
apply(map)
  • 閉包

閉包是 groovy 的一大特性,例如build.gradle中的android{...}埋哟,defaultConfig{...}笆豁,buildTypes{...}dependencies{...}等 這些都是閉包的使用

使用

def add(a,Closure c){
    println a + c.call()
}

add(1,{2+3})
add 1,{
    5+6
}

結(jié)果

6
12

使用2

def myprintln(Closure c){
    println c.call()
}

myprintln {
    123
}
myprintln {
    "Msss"
}
myprintln {
    123+"Msss"
}

結(jié)果2

123
Msss
123Msss

Android Studio的build.gradle代碼整合優(yōu)化

繼續(xù)來說關(guān)于build.gradle代碼優(yōu)化赤赊。這邊我們拿最開始的build.gradle代碼進(jìn)行優(yōu)化闯狱。
說是優(yōu)化,其實(shí)就是吧一些東西寫在另一個(gè)gradle文件下抛计,然后直接調(diào)用就好了哄孤。而且把部分參數(shù)寫在另一個(gè)gradle中,修改這些代碼的時(shí)候吹截,就根本不需要Sync build.gradle代碼瘦陈,也算加快了編譯速度吧!

首先我們?cè)陧?xiàng)目的project目錄下新建一個(gè)config.gradle文件
注:要讓config.gradle代碼能夠在app的build.gradle中使用波俄,在主項(xiàng)目的build.gradle中加入 apply from:'config.gradle' 表示導(dǎo)入config文件代碼
具體位置如下

apply from:'config.gradle'
buildscript {
    repositories {
        ....
    }
    dependencies {
        ....
    }
}

allprojects {
    repositories {
        ....
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

創(chuàng)建好config.gradle文件之后寫入一個(gè)ext{}
默認(rèn)如下

ext{
    
}

然后我們看下晨逝,哪些可以寫在config中
這邊我選了簽名相關(guān)APP的版本懦铺、正式版和測(cè)試版之間相同的數(shù)據(jù)設(shè)置捉貌、加載第三方庫(kù)dependencies相關(guān)這幾項(xiàng)
所以我在config中加入

ext{
    SigningConfigs = [
        
    ]
    DefaultConfig = [

    ]
    Release = [

    ]
    Debug = [

    ]
    Dependencies = [

    ]
}

之后我們對(duì)比原來的build.gradle進(jìn)行配置config文件

ext{
    SigningConfigs = [
            keyAlias : 'gjn',
            keyPassword : '11223344',
            storeFile : 'D:/project/MyDemo/gjnKey.jks',
            storePassword : '11223344'
    ]
    DefaultConfig = [
            versionCode : 1,
            versionName : "1.0"
    ]
    Release = [
            "Host_bcf":"release_Host",
            "appname_res": "myMode",
            "test_key_mp": "release_key"
    ]
    Debug = [
            "Host_bcf":"debug_Host",
            "appname_res": "myModedebug",
            "test_key_mp": "debug_key"
    ]
    Dependencies = [
            appcompat:'com.android.support:appcompat-v7:26.1.0',
            design:'com.android.support:design:26.1.0',
            constraint:'com.android.support.constraint:constraint-layout:1.0.2',
            butterknife:'com.jakewharton:butterknife:8.7.0',
            glide:'com.github.bumptech.glide:glide:3.7.0',
            gson:'com.google.code.gson:gson:2.8.0',
            okhttp:'com.squareup.okhttp3:okhttp:3.8.1',
            rxjava:'io.reactivex.rxjava2:rxjava:2.1.1',
            rxandroid:'io.reactivex.rxjava2:rxandroid:2.0.1',
            retrofit:'com.squareup.retrofit2:retrofit:2.3.0',
            adapterrxjava2:'com.squareup.retrofit2:adapter-rxjava2:2.3.0',
            convertergson:'com.squareup.retrofit2:converter-gson:2.3.0',
    ]
}

現(xiàn)在看下如何在build.gradle中使用
首先先創(chuàng)建好對(duì)應(yīng)的def

def sc = rootProject.ext.SigningConfigs
def dc = rootProject.ext.DefaultConfig
def r = rootProject.ext.Release
def d = rootProject.ext.Debug
def dep = rootProject.ext.Dependencies

之后就只要在用到的地方把原來的參數(shù)替換掉就好了
好比

    //簽名配置
    signingConfigs {
        //簽名Name
        config {
            //簽名別名
            keyAlias 'gjn'
            //簽名別名密碼
            keyPassword '11223344'
            //簽名文件位置
            storeFile file('D:/project/MyDemo/gjnKey.jks')
            //簽名密碼
            storePassword '11223344'
        }
    }

就變成了

    //簽名配置
    signingConfigs {
        //簽名Name
        config {
            //簽名別名
            keyAlias sc.keyAlias
            //簽名別名密碼
            keyPassword sc.keyPassword
            //簽名文件位置
            storeFile file(sc.storeFile)
            //簽名密碼
            storePassword sc.storePassword
        }
    }

使用是很簡(jiǎn)單的,這邊要提及下第三方庫(kù)導(dǎo)入相關(guān)冬念,這邊可以用上面學(xué)的groovy循環(huán)直接一次性全部加進(jìn)去趁窃。可以省略很多代碼急前。
直接改成

dep.each{ k,v->
        implementation v
    }

就等于加入了第三方引用

修改后的build.gradle如下

apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.butterknife'

def sc = rootProject.ext.SigningConfigs
def dc = rootProject.ext.DefaultConfig
def r = rootProject.ext.Release
def d = rootProject.ext.Debug
def dep = rootProject.ext.Dependencies

android {
    //簽名配置
    signingConfigs {
        //簽名Name
        config {
            //簽名別名
            keyAlias sc.keyAlias
            //簽名別名密碼
            keyPassword sc.keyPassword
            //簽名文件位置
            storeFile file(sc.storeFile)
            //簽名密碼
            storePassword sc.storePassword
        }
    }
    //開發(fā)環(huán)境版本號(hào)
    compileSdkVersion 26
    //默認(rèn)配置
    defaultConfig {
        //Id
        applicationId "com.gjn.mydemo"
        //最小支持版本號(hào)
        minSdkVersion 19
        //運(yùn)行版本號(hào)
        targetSdkVersion 25
        //appCode
        versionCode dc.versionCode
        //app版本號(hào)
        versionName dc.versionName
        //測(cè)試相關(guān)
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    //Build類型 默認(rèn)有release和debug兩個(gè)版本
    buildTypes {
        release {
            //是否開始混淆
            minifyEnabled false
            //混淆文件路徑
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //打包時(shí)候調(diào)用的簽名
            signingConfig signingConfigs.config
            //在BuildConfig生成一個(gè)String類型的Host=release_Host
            //即 public static final String Host = "release_Host";
            buildConfigField "String", "Host", "\"${r.Host_bcf}\""
            //編譯之后會(huì)在res文件中的string.xml中加入一個(gè)string類型的app_name1=myMode
            //即 <string name="app_name1">myMode</string>
            resValue "string", "app_name1", "${r.appname_res}"
            //修改build之后的app名稱
            //這邊編譯出來的名字是 release_1.0.apk
            //這個(gè)寫法是Android Studio 3.0之后的方法
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "${variant.name}_${variant.versionName}.apk"
                }
            }
        }
        debug {
            //為Id添加后綴 這邊生成新的Id為com.gjn.mydemo.debug
            applicationIdSuffix ".debug"
            //這邊下面和上面是一樣

            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("String", "Host", "\"${d.Host_bcf}\"")
            resValue("string", "app_name1", "${d.appname_res}")

            //占位符 替換AndroidManifest.xml 中的${test_key}字符
            //AndroidManifest.xml中的源代碼為
            //<meta-data android:name="TEST_KEY" android:value="${test_key}"/>
            //替換之后
            //<meta-data android:name="TEST_KEY" android:value="debug_key"/>
            manifestPlaceholders = ["test_key": "${d.test_key_mp}"]
        }
    }
    //多版本
    productFlavors{
        //dev版本
        dev{
            manifestPlaceholders = ["test_key": "${r.test_key_mp}"]
        }
        //free版本
        free{
            //這邊在提下醒陆,由于free也會(huì)有release和debug兩個(gè)版本
            //release的Id為com.gjn.mydemo.free
            //debug的Id為com.gjn.mydemo.free.debug
            applicationIdSuffix ".free"
            manifestPlaceholders = ["test_key": "free_key"]
        }
    }
    //遍歷了全部版本
    productFlavors.all{
        //設(shè)置統(tǒng)一Code Android Studio 3.0之后需要設(shè)置這個(gè)屬性 不然構(gòu)建多版本的時(shí)候會(huì)報(bào)錯(cuò)
        flavorDimensions("versionCode")
    }
}
//導(dǎo)入第三方之類的jar aar 等 就不說了
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0'
    dep.each{ k,v->
        implementation v
    }
}

這樣就把一些build.gradle中的配置分離出來了。到時(shí)候需要修改的時(shí)候叔汁,大部分只需要修改config文件就好了统求。其實(shí)優(yōu)化下來检碗,也就導(dǎo)入第三方庫(kù)這塊算是優(yōu)化了(:з」∠)


Gradle打包

關(guān)于說打包之前,先說下Gradle的3個(gè)操作
復(fù)制Copy
刪除Delete
壓縮Zip

  • Copy

下面做一個(gè)任務(wù)码邻,將/src/main/xml下的*.xml文件復(fù)制到/build/xml文件夾下

task CopyXml(type: Copy){
    includeEmptyDirs = false
    destinationDir = file('build')
    from( 'src/main/xml') {
        include '**.xml'
        into ('xml')
    }
}
效果
  • Delete

刪除任務(wù)就是吧剛才的文件夾刪除

task DeleteXml(type: Delete){
    delete 'build/xml', 'src/main/xml'
    followSymlinks = true
}

效果就不截圖了折剃。就是刪除掉了兩個(gè)文件夾

  • Zip

壓縮任務(wù)。將app目錄下的app.iml文件壓縮到build目錄下的adc.zip中的zip文件夾下像屋。

task ZipTest(type: Zip){
    destinationDir = file('build')
    archiveName =  'abc.zip'

    from('.'){
        include('app.iml')
        into('zip')
    }
}
壓縮結(jié)果

壓縮包

知道了上面3個(gè)操作怕犁。就可以開始進(jìn)行Gradle打包操作了!

以下項(xiàng)目example為例子原例子代碼

.
├── example
│   ├── build.gradle
│   ├── example.iml
│   ├── proguard-rules.pro
│   └── src
├── libs
│   ├── armeabi
│   ├── armeabi-v7a
│   ├── com.umeng.fb.5.3.0.jar
│   ├── mips
│   └── x86
├── releasenote.txt
└── res
    ├── anim
    ├── drawable
    ├── drawable-xhdpi
    ├── layout
    ├── values
    └── values-zh

首先我們要知道己莺,打包一個(gè)jar需要哪些步驟

  1. 編譯工程(源代碼)導(dǎo)出jar文件
  2. 復(fù)制"example"工程到"outputs/example"目錄
  3. 復(fù)制jar文件到"outputs/libs"目錄
  4. 復(fù)制資源文件到"outputs/res"目錄
  5. 把 "outputs" 目錄壓縮成 zip 文件

之后就可以寫入代碼了

task dabao(type:Zip, dependsOn:build) { 
    destinationDir = file('outputs') 
    duplicatesStrategy = 'exclude' 
    archiveName = 'com.umeng.fb.' + android.defaultConfig.versionName + '.zip' 
    
    from('/'){ 
        include 'releasenote.txt' 
    } 
    into('example') { 
        from '../example' exclude '**/build/**' 
    } 
    from('src/main/res'){ 
        into 'res' 
    } 
    from('libs'){ 
        into 'libs' 
    } 
    from(zipTree('build/outputs/aar/sdk-release.aar')){ 
       include 'classes.jar' 
       rename 'classes.jar','com.umeng.fb.' + android.defaultConfig.versionName + '.jar' 
       into 'libs' 
    }
}

資料

Gradle 完整指南(Android)
看不懂的build.gradle代碼
學(xué)點(diǎn)Groovy來理解build.gradle代碼
如果像寫代碼一樣寫Gradle腳本
Gradle使用技巧總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奏甫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凌受,更是在濱河造成了極大的恐慌阵子,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胜蛉,死亡現(xiàn)場(chǎng)離奇詭異挠进,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)誊册,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門领突,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人案怯,你說我怎么就攤上這事君旦。” “怎么了嘲碱?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵金砍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我悍汛,道長(zhǎng)捞魁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任离咐,我火速辦了婚禮谱俭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宵蛀。我一直安慰自己昆著,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布术陶。 她就那樣靜靜地躺著凑懂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪梧宫。 梳的紋絲不亂的頭發(fā)上接谨,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天摆碉,我揣著相機(jī)與錄音,去河邊找鬼脓豪。 笑死巷帝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扫夜。 我是一名探鬼主播楞泼,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼笤闯!你這毒婦竟也來了堕阔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤颗味,失蹤者是張志新(化名)和其女友劉穎超陆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浦马,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侥猬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捐韩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹃锈,死狀恐怖荤胁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屎债,我是刑警寧澤仅政,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站盆驹,受9級(jí)特大地震影響圆丹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躯喇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一辫封、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧廉丽,春花似錦倦微、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至焦履,卻和暖如春拓劝,著一層夾襖步出監(jiān)牢的瞬間雏逾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工郑临, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留栖博,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓牧抵,卻偏偏與公主長(zhǎng)得像笛匙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子犀变,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359