Android软件中gradle的配置

gradle.png

1.构建Android应用程序的Gradle。
1.1 使用Gradle Android应用程序。
默认情况下,Android项目由Gradle构建系统处理。如果你在Android studio中创建一个新项目,则会自动创建Gradle构建脚本。Android Studio提供了Gradle运行时,因此不需要额外的安装。

如果你按下Android Studio中的run按钮,则会触发相应的Gradle任务并启动应用程序。

你也可以通过命令行运行Gradle。为了避免不必要的本地安装,Gradle提供了一个包装器脚本,允许您在没有任何本地安装的情况下运行Gradle。

1.2 从源代码到Android应用程序的转换过程。
Java源代码文件由Java编译器转换为Java类文件。Android SDK包含一个名为dx的工具,它将Java类文件转换为.dex(Dalvik Executable)文件。应用程序的所有类文件都放在此.dex文件中。在此转换过程中,类文件中的冗余信息在.dex文件中进行优化。例如,如果String在不同的类文件中找到相同的文件,则.dex文件只包含一个引用String。

因此,这些.dex文件的大小要比相应的类文件小得多。

该.DEX文件和其他资源,例如图像和XML文件,被打包成一个apk文件(Android Package的)文件。程序aapt(Android资产打包工具)执行此步骤。

所得的.apk文件包含运行Android应用程序的所有必要数据,并可通过adb工具部署到Android设备。

从Android 5.0起,Android RunTime(ART)被用作所有Android应用的运行时。ART采用“时尚之都”和“时尚_汇编”的组合。在Android设备上安装应用程序期间,将应用程序代码转换为机器代码。

该dex2oat工具使用Android工具链创建的.dex文件,并将其编译为可执行和可链接格式(ELF文件)。该文件包含dex代码,编译的本地代码和元数据。保持.dex代码允许现有的工具仍然可以工作。

1.3 在命令行中使用Gradle。
Gradle构建系统旨在支持创建Android应用程序时的复杂场景:

1)多分销:同一应用程序必须为几个客户或公司定制
2)Multi-apk:支持为不同设备类型创建多个apk,同时重用部分代码

你可以通过命令行启动Gradle构建。以下是Android Gradle重要任务的概述:
表1. Android Gradle构建目标

命令  描述
./gradlew build
构建项目,运行组合和检查任务
./gradlew clean build
从零开始构建项目
./gradlew clean build
从零开始构建项目
./gradlew test
运行测试
./gradlew connectedAndroidTest
运行仪器测试

要查看所有可用任务,请使用gradlew wrapper命令。

gradle build
# alternatively speedup second grandle build by holding it in memory
# gradle build --daemon

此命令将创建构建文件夹中的摇篮构建的输出。默认情况下,Gradle构建在build / outputs / apk文件夹中创建两个.apk文件。
要在JVM上构建和启动单元测试,请使用以下命令。

gradle test

此命令将创建构建文件夹中的摇篮构建的输出。默认情况下,Gradle构建在build / outputs / apk文件夹中创建两个.apk文件。
要在JVM上构建和启动单元测试,请使用以下命令。

gradle connectedCheck

要在Android设备上构建和启动仪器化测试,请使用以下命令。

gradle connectedCheck

1.4 通过资源缩小来删除未使用的资源和Java类。
用于Android的Gradle构建系统支持在构建时缩小资源。这将自动从打包的应用程序中删除未使用的资源。除此之外,还可以从你所依赖的库中删除不必要的资源。这可以大大减少你的应用程序的大小。
要使资源缩小,请更新你的构建文件,类似于以下代码段。

android {
    ...

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

1.5 定义依赖关系并保留外部版本。
一个很好的做法是在依赖关系之外定义库依赖的版本,以便更好的维护。

ext {
    // App dependencies
    junitVersion = '4.12'
    mockitoVersion = '1.10.19'
    powerMockito = '1.6.2'
    hamcrestVersion = '1.3'
}

dependencies {
    // Dependencies for local unit tests
    testCompile "junit:junit:$junitVersion"
    testCompile "org.mockito:mockito-all:$mockitoVersion"
    testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
    testCompile "org.powermock:powermock-module-junit4:$powerMockito"
    testCompile "org.powermock:powermock-api-mockito:$ext.powerMockito"
}

2.1 构建类型并构建风格。
Android默认使用两种构建类型:调试和释放。对于这些构建类型,你可以在Gradle构建中创建不同的风格。
Gradle构建系统还能够管理不同风格的应用程序。产品风味定义了应用程序的定制版本。这允许代码库的某些部分或资源对于应用程序的变体而有所不同。
例如,你可以为某些设备类别(如手机或平板电脑)定义不同的构建版本。另一个用例可能是您的应用的付费或免费版本。或者您想在测试运行期间使用不同的资源或类。

2.2 在你的Gradle构建文件中定义产品风格。
你可以使用 productFlavors关闭app / build.gradle文件来定义产品的不同变体。

productFlavors {
    prod {
        applicationId = "com.vogella.android.gradlebuildflavors.prod"
        versionName = "1.0-paid"
    }

    mock {
        applicationId = "com.vogella.android.gradlebuildflavors.mock"
        versionName = "1.0-free"
    }
}

整个build.gradle文件可能如下所示:

apply plugin: 'com.android.application'

android {
    //  ....

    productFlavors {
        prod {
            applicationId = "com.vogella.android.gradlebuildflavors.prod"
            versionName = "1.0-paid"
        }

        mock {
            applicationId = "com.vogella.android.gradlebuildflavors.mock"
            versionName = "1.0-free"
        }
    }
}

// ...

定义这些flavor之后,您可以在Android Studio 的“ 构建变体”视图中选择它们。

1.PNG

2.3 为flavor提供不同的资源
为了为某种风格定义不同的行为,您需要为app / src /下定义的风格创建合适的文件夹。
风味特定资源将覆盖主要资源。例如,如果您在一个风味中提供了不同的应用程序图标,Android构建系统就会获得特定的风格。

2.4 为 app的flavor提供不同的来源集。
src /文件夹中的目录称为源集。每个产品的味道都可以定义自己的源集。
代码文件不被替换为资源,它们被组合。例如,你不能com.example.MainActivity在你的app / main / java /文件夹中有一个 活动,另外一个不同的实现是另外一种。如果您尝试这样做,您将收到有关重复类定义的错误消息。
您仍然可以通过避免在主源文件夹中创建类来提供不同的实现,而在每种风格中创建一个类。

3.可选练习:为应用程序使用不同的产品风格。
在本练习中,您将创建一个具有两种不同项目风格的Android应用程序,称为prod和mock。
模拟版本定义与prod版本不同的资源。在第一个示例中, folder/project的strings.xml文件被覆盖。构建变体是通过Build Variants view定义的。

3.1 创建一个新的Android应用程序。
使用Empty Activity模板和顶级包创建一个新项目com.vogella.android.gradlebuildflavors
app / build.gradle文件中定义两个额外的产品flavor,称为“prod”和“mock”。

apply plugin: 'com.android.application'

android {
  //...

    productFlavors {
        prod {
            applicationId = "com.vogella.android.gradlebuildflavors.prod"
            versionName = "1.0-paid"
        }

        mock {
            applicationId = "com.vogella.android.gradlebuildflavors.mock"
            versionName = "1.0-free"
        }
    }
}

为产品和模拟flavors创建所需的文件夹结构。


2.PNG

将strings.xml从主文件夹复制到flavor的相应文件夹。

hello_worldstrings.xml的字符串更改为Mock World!和产世界!So....

<resources>
    <string name="app_name">Flavor</string>
    <string name="hello_world">Mock World! </string>
</resources>
<resources>
    <string name="app_name">Flavor</string>
    <string name="hello_world">Prod World! </string>
</resources>
...1.PNG

3.2 验证
在Android Studio 的Build Variants view中选择mockDebug“ 构建变体”,并运行你的应用程序。

....PNG

如果你启动应用程序,你应该看到从模拟的flavor的string。现在选择你的flavor 启动它,你应该看到另一个string。

3.3 通过Gradle命令行构建
使用该./gradlew build命令构建您的所有产品flavor。

3.4 准备您的应用程序测试与Gradle flavor。
ShareIntentBuilder通过使用以下代码的静态方法创建一个通过“share intent”启动活动的类。

import android.content.Context;
import android.content.Intent;

public class ShareIntentBuilder {

    public static void startSendActivity(Context context, String title, String body) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TITLE, title);
        intent.putExtra(Intent.EXTRA_TEXT, body);
        intent.setType("text/plain");
        Intent chooserIntent = Intent.createChooser(intent, context.getResources().getText(R.string.share));
        chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(chooserIntent);
    }

3.5 为您的口味实现不同的MainActivity版本。
允许触发此意图的活动在您的“mock” flavor中被替换。如果选择了“mock”,则在应用程序中启动显示发送数据的第二个活动。如果选择flavor “prod”,则发送shared intent。

  1. 自定义Gradle构建
    4.1 重命名输出apk。
apply plugin: 'com.android.application'

android {
    // more
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
       applicationVariants.all { variant ->
           variant.outputs.each { output ->
               def file = output.outputFile
               def filename = file.name.replace("app", "lars")
               output.outputFile = new File(file.parent, filename)

           }
       }
// more
}

4.2 为调试版本指定不同的密钥库。
您可以在build.gradle文件中定义密钥库。
例如,您可以重新定义调试变量的密钥库:

android {
    signingConfigs {
        debug {
            storeFile file("your.keystore")
        }
    }
}
  1. 将使用Eclipse创建的Android项目迁移到Gradle
    5.1 将基于Eclipse的Android项目导入到Android Studio中。
    Android项目有两种不同的配置。第一套项目使用Eclipse ADT工具使用的遗留项目结构,直到2013年使用。第二套项目使用新的Gradle构建结构。Gradle可以配置为支持两种格式,Eclipse项目结构和Gradle项目结构。

一旦你添加一个有效的Gradle 文件到你的基于Eclipse的Android项目,你可以将其导入到Android Studio中,通过File Import Project,并通过与Gradle 中选择项目文件夹中建立文件。

5.2 为您的基于Eclipse的Android项目添加一个Gradle文件。
要启用基于Eclipse的Android项目的Gradle构建,将以下build.gradle添加到项目的根目录中。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-beta3'
    }
}
apply plugin: 'com.android.application'


android {
     lintOptions {
          abortOnError false
      }

    compileSdkVersion 22
    buildToolsVersion "21.1.2"

        defaultConfig {
            targetSdkVersion 22
        }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

      
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}

1.构建Android应用程序的Gradle。
1.1 使用Gradle Android应用程序。
默认情况下,Android项目由Gradle构建系统处理。如果你在Android studio中创建一个新项目,则会自动创建Gradle构建脚本。Android Studio提供了Gradle运行时,因此不需要额外的安装。

如果你按下Android Studio中的run按钮,则会触发相应的Gradle任务并启动应用程序。

你也可以通过命令行运行Gradle。为了避免不必要的本地安装,Gradle提供了一个包装器脚本,允许您在没有任何本地安装的情况下运行Gradle。

1.2 从源代码到Android应用程序的转换过程。
Java源代码文件由Java编译器转换为Java类文件。Android SDK包含一个名为dx的工具,它将Java类文件转换为.dex(Dalvik Executable)文件。应用程序的所有类文件都放在此.dex文件中。在此转换过程中,类文件中的冗余信息在.dex文件中进行优化。例如,如果String在不同的类文件中找到相同的文件,则.dex文件只包含一个引用String。

因此,这些.dex文件的大小要比相应的类文件小得多。

该.DEX文件和其他资源,例如图像和XML文件,被打包成一个apk文件(Android Package的)文件。程序aapt(Android资产打包工具)执行此步骤。

所得的```.apk````文件包含运行Android应用程序的所有必要数据,并可通过adb工具部署到Android设备。

从Android 5.0起,Android RunTime(ART)被用作所有Android应用的运行时。ART采用“时尚之都”和“时尚_汇编”的组合。在Android设备上安装应用程序期间,将应用程序代码转换为机器代码。

该dex2oat工具使用Android工具链创建的.dex文件,并将其编译为可执行和可链接格式(ELF文件)。该文件包含dex代码,编译的本地代码和元数据。保持.dex代码允许现有的工具仍然可以工作。

1.3 在命令行中使用Gradle。
Gradle构建系统旨在支持创建Android应用程序时的复杂场景:

1)多分销:同一应用程序必须为几个客户或公司定制
2)Multi-apk:支持为不同设备类型创建多个apk,同时重用部分代码

你可以通过命令行启动Gradle构建。以下是Android Gradle重要任务的概述:
表1. Android Gradle构建目标

命令  描述
./gradlew build
构建项目,运行组合和检查任务
./gradlew clean build
从零开始构建项目
./gradlew clean build
从零开始构建项目
./gradlew test
运行测试
./gradlew connectedAndroidTest
运行仪器测试

要查看所有可用任务,请使用gradlew wrapper命令。

gradle build
# alternatively speedup second grandle build by holding it in memory
# gradle build --daemon

此命令将创建构建文件夹中的摇篮构建的输出。默认情况下,Gradle构建在build / outputs / apk文件夹中创建两个.apk文件。
要在JVM上构建和启动单元测试,请使用以下命令。

gradle test

此命令将创建构建文件夹中的摇篮构建的输出。默认情况下,Gradle构建在build / outputs / apk文件夹中创建两个.apk文件。
要在JVM上构建和启动单元测试,请使用以下命令。

gradle connectedCheck

要在Android设备上构建和启动仪器化测试,请使用以下命令。

gradle connectedCheck

1.4 通过资源缩小来删除未使用的资源和Java类。
用于Android的Gradle构建系统支持在构建时缩小资源。这将自动从打包的应用程序中删除未使用的资源。除此之外,还可以从你所依赖的库中删除不必要的资源。这可以大大减少你的应用程序的大小。
要使资源缩小,请更新你的构建文件,类似于以下代码段。

android {
    ...

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

1.5 定义依赖关系并保留外部版本。
一个很好的做法是在依赖关系之外定义库依赖的版本,以便更好的维护。

ext {
    // App 依赖
    junitVersion = '4.12'
    mockitoVersion = '1.10.19'
    powerMockito = '1.6.2'
    hamcrestVersion = '1.3'
}

dependencies {
    // 单元测试依靠
    testCompile "junit:junit:$junitVersion"
    testCompile "org.mockito:mockito-all:$mockitoVersion"
    testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
    testCompile "org.powermock:powermock-module-junit4:$powerMockito"
    testCompile "org.powermock:powermock-api-mockito:$ext.powerMockito"
}

2.1 构建类型并构建风格。
Android默认使用两种构建类型:调试和释放。对于这些构建类型,你可以在Gradle构建中创建不同的风格。
Gradle构建系统还能够管理不同风格的应用程序。产品风味定义了应用程序的定制版本。这允许代码库的某些部分或资源对于应用程序的变体而有所不同。
例如,你可以为某些设备类别(如手机或平板电脑)定义不同的构建版本。另一个用例可能是您的应用的付费或免费版本。或者您想在测试运行期间使用不同的资源或类。

2.2 在你的Gradle构建文件中定义产品风格。
你可以使用 productFlavors关闭app / build.gradle文件来定义产品的不同变体。

productFlavors {
    prod {
        applicationId = "com.vogella.android.gradlebuildflavors.prod"
        versionName = "1.0-paid"
    }

    mock {
        applicationId = "com.vogella.android.gradlebuildflavors.mock"
        versionName = "1.0-free"
    }
}

整个build.gradle文件可能如下所示:

apply plugin: 'com.android.application'

android {
    //  ....

    productFlavors {
        prod {
            applicationId = "com.sangmsen.android.gradlebuildflavors.prod"
            versionName = "1.0-paid"
        }

        mock {
            applicationId = "com.sangmesen.android.gradlebuildflavors.mock"
            versionName = "1.0-free"
        }
    }
}

// ...

定义这些flavor之后,您可以在Android Studio 的“ 构建变体”视图中选择它们。

1.PNG

2.3 为flavor提供不同的资源
为了为某种风格定义不同的行为,您需要为app / src /下定义的风格创建合适的文件夹。
flavor特定资源将覆盖主要资源。例如,如果你在一个风味中提供了不同的应用程序图标,Android构建系统就会获得特定的风格。

2.4 为 app的flavor提供不同的来源集。
src /文件夹中的目录称为源集。每个产品的flavor都可以定义自己的源集。
代码文件不被替换为资源,它们被组合。例如,你不能com.example.MainActivity在你的app / main / java /文件夹中有一个 活动,另外一个不同的实现是另外一种。如果您尝试这样做,你将收到有关重复类定义的错误消息。
你仍然可以通过避免在主源文件夹中创建类来提供不同的实现,而在每种风格中创建一个类。

3.可选练习:为应用程序使用不同的产品风格。
在本练习中,您将创建一个具有两种不同项目风格的Android应用程序,称为prod和mock。
模拟版本定义与prod版本不同的资源。在第一个示例中, folder/project的strings.xml文件被覆盖。构建变体是通过Build Variants view定义的。

3.1 创建一个新的Android应用程序。
使用Empty Activity模板和顶级包创建一个新项目com.sangmsen.android.gradlebuildflavors
app / build.gradle文件中定义两个额外的产品flavor,称为“prod”和“mock”。

apply plugin: 'com.android.application'

android {
  //...

    productFlavors {
        prod {
            applicationId = "com.sangmsen.android.gradlebuildflavors.prod"
            versionName = "1.0-paid"
        }

        mock {
            applicationId = "com.sangmsen.android.gradlebuildflavors.mock"
            versionName = "1.0-free"
        }
    }
}

为产品和模拟flavors创建所需的文件夹结构。


2.PNG

将strings.xml从主文件夹复制到flavor的相应文件夹。

hello_worldstrings.xml的字符串更改为Mock World!和产世界!So....

<resources>
    <string name="app_name">Flavor</string>
    <string name="hello_world">Mock World! </string>
</resources>
<resources>
    <string name="app_name">Flavor</string>
    <string name="hello_world">Prod World! </string>
</resources>
...1.PNG

3.2 验证
在Android Studio 的Build Variants view中选择mockDebug“ 构建变体”,并运行你的应用程序。

....PNG

如果你启动应用程序,你应该看到从模拟的flavor的string。现在选择你的flavor 启动它,你应该看到另一个字符串。

3.3 通过Gradle命令行构建
使用该./gradlew build命令构建您的所有产品口味。

3.4 准备您的应用程序测试与Gradle flavor。
ShareIntentBuilder通过使用以下代码的静态方法创建一个通过“share intent”启动活动的类。

import android.content.Context;
import android.content.Intent;

public class ShareIntentBuilder {

    public static void startSendActivity(Context context, String title, String body) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TITLE, title);
        intent.putExtra(Intent.EXTRA_TEXT, body);
        intent.setType("text/plain");
        Intent chooserIntent = Intent.createChooser(intent, context.getResources().getText(R.string.share));
        chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(chooserIntent);
    }

3.5 为您的口味实现不同的MainActivity版本。
允许触发此意图的活动在您的“mock” flavor中被替换。如果选择了“mock”,则在应用程序中启动显示发送数据的第二个活动。如果选择flavor “prod”,则发送shared intent。

  1. 自定义Gradle构建
    4.1 重命名输出apk。
apply plugin: 'com.android.application'

android {
    // more
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
       applicationVariants.all { variant ->
           variant.outputs.each { output ->
               def file = output.outputFile
               def filename = file.name.replace("app", "lars")
               output.outputFile = new File(file.parent, filename)

           }
       }
// more
}

4.2 为调试版本指定不同的密钥库。
您可以在build.gradle文件中定义密钥库。
例如,您可以重新定义调试变量的密钥库:

android {
    signingConfigs {
        debug {
            storeFile file("your.keystore")
        }
    }
}
  1. 将使用Eclipse创建的Android项目迁移到Gradle
    5.1 将基于Eclipse的Android项目导入到Android Studio中。
    Android项目有两种不同的配置。第一套项目使用Eclipse ADT工具使用的遗留项目结构,直到2013年使用。第二套项目使用新的Gradle构建结构。Gradle可以配置为支持两种格式,Eclipse项目结构和Gradle项目结构。

一旦你添加一个有效的Gradle 文件到你的基于Eclipse的Android项目,你可以将其导入到Android Studio中,通过File Import Project,并通过与Gradle 中选择项目文件夹中建立文件。

5.2 为您的基于Eclipse的Android项目添加一个Gradle文件。
要启用基于Eclipse的Android项目的Gradle构建,将以下build.gradle添加到项目的根目录中。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-beta3'
    }
}
apply plugin: 'com.android.application'


android {
     lintOptions {
          abortOnError false
      }

    compileSdkVersion 22
    buildToolsVersion "21.1.2"

        defaultConfig {
            targetSdkVersion 22
        }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

      
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容