2020-05-22

从HelloWorld开始了解Android

我相信任何学习编程的人,刚开始都会接触一个项目,那就是 HelloWorld 。一般来说,这是每一种计算机编程语言中最基本、最简单的程序,亦通常是初学者所编写的第一个程序。它还可以用来确定(测试)该语言的编译器、程序开发环境,以及运行环境是否已经安装妥当,将输出字符串“Hello World”作为第一个示范程序,现在已经成为编程语言学习的传统,接下来让我们来创建第一个程序Hello World

1.运行AndroidStudio,新建一个AndroidStudio工程,会进入到欢迎界面

在这里插入图片描述

我们鼠标左键点击Start a new Android Studio project会打开一个创建新项目的界面,如下图所示。

在这里插入图片描述

其中Application name表示应用名称,如果安装到手机上之后会显示该名称,可以看到我们输入了HelloWorldCompany Domain表示公司域名,如果你是个人开发者,没有公司域名的话,那么可以填example.com就可以了。Package name表示项目的 包名,Android系统是通过包名来区分不同程序的,因此包名一定要具有唯一性。Android Studio会根据应用名称(Application name)和公司域名(Company Domain)来自己生成合适的包名,如果你不想使用默认生成的包名,也可以点击右侧的Edit按钮自行修改,Project location表示项目代码存放的位置,如果没有特殊要求的话,这里也可以不修改(==尽量设置在除系统盘的任意地方==)。接下来点击Next可以对项目的最低兼容版本进行设置。如下图所示

在这里插入图片描述

这里我们将Minimum SDK指定成API 15 就可以了。另外,Wear、TV、Android Auto 属于其他移动设备上需要的版本,这里我们就不仔细讲了。点击Next会跳转到创建活动界面,这里我们可以选择一种模式,如下图所示。

在这里插入图片描述

可以看到,Android Studio提供了很多种内置模板,不过由于我们还是初学者,还用不到那么多复查的模板,这里直接选择Empty Activity来创建一个空的活动就可以了。

继续点击Next,可以给创建的活动和布局命名。如下图所示

在这里插入图片描述

Activity Name表示活动的名字,我们这里使用默认的MainActivity,Layout Name表示布局的命名,这里会跟随你的活动名(Activity Name)变化而变化,然后点击Finish按钮,并且耐心等待一会儿,项目就会创建成功了(==PS:可能刚开始你会觉得很慢,不过习惯就好了,这个时候你可以去泡一杯咖啡或者放一首歌来转移你的注意力==),如下图所示

项目创建成功

2.创建模拟器

由于Android Studio自动为我们生成了很多东西,你现在不需要编写任何代码,Hello World已经可以运行了,但是在此之前还必须有一个运行的载体,你可以使用自己的手机,或者是Android 模拟器(==虚拟手机==),我们先用Android 模拟器来运行程序吧。

那么由于是第一次使用,我们需要先创建一个Android模拟器,观察Android Studio 顶部工具栏中的图标,如下图所示

[图片上传失败...(image-a7a290-1590142086178)]

其中左边第一个按钮就是创建和启动模拟器的,点击该按钮,会弹出如下图所示

在这里插入图片描述

因为我之前创建过虚拟机,所以会进入创建的所有虚拟机的列表,现在我们点击Create Virtual Device按钮就可以立刻开始创建了

在这里插入图片描述

我们选择Nexus 5x这台设备作为我们的虚拟机,点击Next,如下图所示

在这里插入图片描述

这里我们可以选择模拟器所使用的操作系统版本,这里我们使用Android 7.0,然后点击Next如下图所示

在这里插入图片描述

这里我们队模拟器的一些配置进行确认,比如说指定模拟器的名字、分辨率、横竖屏等信息,如果没有特殊要求的话,全部保持默认即可。点击Finish完成模拟器的创建,如下图所示

在这里插入图片描述

是不是有点眼熟,我们又见面了,接下来选择第一个虚拟机,点击Actions下面的绿色三角来启动我们的虚拟机。如下图所示

在这里插入图片描述

很清晰的Android界面出来了,是不是和你的手机界面差不多呢?

虚拟机启动好了,接下来我们来运行刚才的HelloWorld项目在虚拟机上,我们观察Android Studio顶部的工具栏中的图标,如下图所示

[图片上传失败...(image-a9cba6-1590142086178)]

其中左边的锤子按钮是用来编译项目的,中间的下拉列表是用来选择哪一个项目的,通常app就是当前的主项目(也就是HelloWorld),右边的三角形按钮使用来运行项目的,现在我们点击右边的运行按钮,会弹出一个选择运行设备的对话框,如下图所示

在这里插入图片描述

可以看到上面的Connected Devices下面的Android模拟器就是我们现在所运行的虚拟手机,而Available Virtual Devices下面的Android模拟器是我们其他的未在运行状态下的Android模拟器,可以看到已经选中了Nexus 5X,点击OK按钮,稍等一会儿项目就会运行在模拟器上面(==PS:如果你的电脑配置不够,建议用自己的手机进行项目运行,否则你的系统运行占用内存会达到80%以上,你就会看到你的电脑卡的动不了,这个时候看网页会让你知道什么事绝望。==)

[图片上传失败...(image-b9c3c9-1590142086178)]

运行时,你会看到Android Studio底部中间的位置,有一个项目编译运行的进度显示,如上图所示,等这个消失之后,可以看到你的虚拟机上面已经运行好了Hello World项目,如下图所示

在这里插入图片描述

现在是程序运行在模拟器上面,接下来我们试一下用自己的手机来运行项目。

3.使用手机运行项目

首先你需要一台Android手机,如果想要将程序运行到手机上,需要通过数据线把手机连接到电脑上。然后进入你手机的设置→系统→关于手机(==从Android 4.2系统开始,开发者选项默认是隐藏的,需要其他的方法来打开这个选项==),打开关于手机你会看到你的设备名称,型号,系统版本,Android版本等一些信息,因为手机有很多的品牌,各品牌启动开发者选项都不一样,你可以搜索(==手机型号+启动开发者选项==),好了现在我们已经启动了开发者选项,如下图所示

在这里插入图片描述

打开USB调试,如果你的电脑是Windows操作系统,我们还需要在电脑上安装手机的驱动。一般借助360手机助手或豌豆荚等工具都可以快速安装(==我使用的是华为手机助手==),如下图所示

在这里插入图片描述

这时候我们点击Android Studio顶部的绿色三角形启动按钮会看到如下图所示

[图片上传失败...(image-49ac49-1590142086178)]

在这里插入图片描述

我们选择自己的手机作为启动载体,点OK按钮,稍等一会儿,这个时候注意观察你的手机,会出现提示你“应用来历不明”是否继续安装,点继续安装然后系统会检测该应用所需要的应用功能权限,没有的话就不会显示这些权限列表,我们点继续安装,安装完成后会自动打开这个项目,如下图所示

[图片上传失败...(image-9a6b79-1590142086178)]

现在项目就已经在手机上运行起来了,这个时候你会想,我明明什么代码都没有打,为什么会有一个Hello World!呢,这时候我们来分析一下Hello World项目吧。

4.分析Android Studio项目

我们回到Android Studio中展开 Hello World项目 如下图所示

在这里插入图片描述

任何一个新建的项目都会默认使用Android模式的项目建构,但这并不是项目真实的目录结构,而是被Android Studio转换过的,这种项目结构简洁明了,适合快速开发,但是对于新手来说可能并不易于理解,点击图中的Android 区域可以切换项目结构模式,如下图所示[图片上传失败...(image-33d4d-1590142086178)]

这里我们将项目结构切换成Project,这就是项目真实的目录结构了,如下图所示

在这里插入图片描述

一下子出现这么多陌生的东西,你一定会感到有点头大吧。那么我们接下来对这里的内容一一解释,之后你看这个图就不会觉得头大了(==PS:还会很亲切呢!==)

5.Project项目结构解析

  1. ==.gradle 和.idea==

这两个目录下放置的都是Android Studio自动生成的一些文件,我们无须关心,也不要去手动编辑。

  1. ==app==

项目的代码、资源等内容几乎都是放置在这个目录下的,我们后面的开发工作也基本都是在这个目录下进行的,待会儿还会对这个目录单独展开进行讲解。

  1. ==build==

这个目录你也不需要过多关心,它主要包含一些在编译时自动生成的文件。

  1. ==gradle==

这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。Android Studio默认没有启动gradle wrapper的方式,如果需要打开,可以点击Android Studio 导航栏→File→Settings→Build, Execution,Deployment→Gradle,进行配置更改。

  1. ==.gitignore==

这个文件是用来将制定的目录或文件排除在版本控制之外的。

  1. ==build.gradle==

这是项目全局的gradle构建脚本,通常这个文件的内容是不需要修改的。稍后我们将会详细分析gradle构建脚本中的具体内容。

  1. ==gradle.properties==

这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。

  1. ==gradlew和gradlew.bat==

这两个文件是用来命令行界面中执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的。

  1. ==HelloWorld.iml==

iml文件是所有Intellij IDEA项目都会自动生成的一个文件(==Android Studio是基于Intellij IDEA开发的==),用于标识这是一个Intellij IDEA项目,我们不需要修改这个文件的任何内容。

10.==local.properties==

这个文件用于指定本机中的Android SDK路径,通常内容都是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。

11.==settings.gradle==

这个文件用于指定项目中所有引入的模块。由于HelloWrold项目中只有一个app模块,因此该文件中也就只引入了app这一个模块。通常情况下模块的引入都是自动完成的,需要我们手动去修改这个文件的场景可能比较少。

现在整个项目的外层结构已经介绍完了,你会发现,除了目录之外,大多数的文件和目录都是自动生成的,我们并不需要进行修改。想必你已经猜到了,接下来我们对app目录下的内容进行解释,目录结构如下图所示

[图片上传失败...(image-b3c244-1590142086178)]

  1. ==build==

这个目录和外层的build目录类似,主要也包含了一些在编译时自动生成的文件,不过它里面的内容会更多更杂,我们不需要过多关系。

  1. ==libs==

    如果你的项目中使用到了第三方jar包,就需要把这些jar包都放在libs目录下,放在这个目录下的jar包都会被自动添加到构建路径里去。

  2. ==androidTest==

此处是用来编写Android Test 测试用例的,可以对项目进行一些自动化测试。

  1. ==java==

这个就是我们的主角了,java目录是放置我们所有java代码的地方,展开该目录,你将看到我们刚才创建的MainActivity文件就在里面。

  1. ==res==

这个目录下的内容就有点多了。简单来说,就是你在项目中使用到的所有图片、布局、字符串等资源都要存放在这个目录下。当然这个目录下还有很多子目录,图片放在drawable目录下,布局放在layout下,字符串放在value目录下。

  1. ==AndroidManifest.xml==

这是你整个Android项目的配置文件,你在程序中定义的四大组件都需要在这个文件里注册,否则就会使用不了,另外还可以在这个文件中给应用程序添加权限声明(==PS:比如网络、电话、通讯、位置、存储等一些权限都是在这个文件里面声明==)。

  1. ==test==

此处是用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。

  1. ==.gitignore==

这个文件用于将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的==.gitignore==文件类似。

  1. ==app.iml==

Intellij IDEA项目自动生成的文件,我们不需要关心或修改这个文件中的内容。

10.==build.gradle==

这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置。

11.==proguard-rules.pro==

这个文件通常用于指定项目代码的混淆规则,当代码开发完成后打成安装包文件,如果不希望代码被别人破解,通常会将代码进行混淆,从而让破解者难以阅读。

好了,我们的整个项目的结构终于介绍完了,不知道你能不能看完,接下来就来分析我们的HelloWorld项目是怎么运行起来的。首先打开AndroidManifest.xml文件,找到如下代码:


<activity android:name=".MainActivity">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

这段代码表示对MainActivity这个活动进行注册,没有在AndroidManifest.xml 里注册的活动是不能使用的,其中intent-filter里面的两行代码非常重要,


<action android:name="android.intent.action.MAIN" />


<category android:name="android.intent.category.LAUNCHER" />

表示MainActivity是这个项目的主活动,在手机上点击应用图标,首先启动的就是这个活动。我们之前在手机上运行看到的界面就是这个,现在我们看一下MainActivity这个活动,代码如下


public class MainActivity extends AppCompatActivity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

    }

}

我们可以看到MainActivity是继承AppCompatActivity的 ,这是一种向下兼容的Activity,可以将Activity在各个版本中增加的特性和功能最低兼容到Android2.1系统。(==AppCompatActivity 是 Activity 的子类==),然看到下面有一个onCreate()方法,这个方法是一个活动被创建时必定要执行的方法,其中有两行代码,也没有看到HelloWorld!的字样,那么我们手机上面显示的HelloWorld!是在哪里呢?

因为Android程序的设计讲究逻辑和视图分离,因此是不推荐在活动中直接编写界面的,通常是在布局文件(==也就是layout文件夹下面==)中编写界面,然后再活动中引入进来,setContentView(R.layout.activity_main);

活动中引入了名为activity_main的xml文件(==也就是布局文件==),我们打开res→layout→activity_main.xml它可以看到

在这里插入图片描述

这个是控件视图界面我们点击Text切换到文字视图界面

在这里插入图片描述

点击最右侧导航栏的Preview可以同时看到你的layout界面。如下图所示

在这里插入图片描述

这样看起来会不会好很多呢。接下来我们来看一下这一段代码


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_main"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context="com.example.helloworld.MainActivity">

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Hello World!" />

</RelativeLayout>

不知道你有没有看到HelloWorld!呢?(==PS:如果没有看到的话,给我发邮箱,我帮你联系一家好医院,包你满意,破盘价只要998,,咳~扯远了,我们回到主题==)

1.布局:RelativeLayout 表示这是一个相对布局,

2.控件:TextView表示这是一个文本控件,它下面有一个text属性,属性的值就是HelloWorld!如果你不想看到这个,你可以改成Love Money!,一定要在英文状态下双引号 " "内才行,如果是中文状态下的会报错,不打引号也会报错。

接下来我们详细说一下res目录,这个很重要,我们先看一下他的结构

[图片上传失败...(image-99af8a-1590142086178)]

上面的文件夹虽然很多,但我们分析一下其实就是非常简单了,所有以drawable开头的文件夹都是用来放图片,所有以mipmap开头的文件夹都是放应用图标的,所有以values开头的文件夹都是用来放字符串、颜色、样式等配置的,layout文件夹,前面我们说到是用来放布局文件的。(==PS:是很简单吧!==),知道了含义,我们再来看一下如何使用这些资源

打开res/values/strings.xml文件


<resources>

    <string name="app_name">HelloWorld</string>

</resources>

可以看到这里定义了应用程序名的字符串,这个名字就是你的应用名(==PS:再简单一点说就是,你手机上某个APP软件的文字==),为什么我们的程序会是这个名字呢,那是因为你一开始创建项目的时候就是这个,不过不用担心也是可以改的,比如改成LoveMoney,手动滑稽。我们在其他地方是会引用这个名称的。

1.在代码里通过R.String.app_name来获得该字符串的引用。

2.在XML里面通过@string/app_name来获得该字符串的引用。(==其实第二种,我们已经见过了,不知道你注意到没有,在AndroidManifest.xml里面,现在打开这个文件,如下图所示==)

在这里插入图片描述

还有我们的应用程序的图标是通过android:icon属性来指定的,应用的名称则是通过android:label属性来指定的,你会看到一个绿色的机器人(==PS:不管你觉得丑不丑,我觉得是挺丑的!==)


android:icon="@mipmap/ic_launcher"

你在mipmap文件夹下放其他的图标,注意,所有的mipmap开头的文件都要放。将自带的ic_launcher图标,改为你喜欢的图标就可以了。

6.详解build.gradle文件

我们之前看到最外层有一个build.gradle文件,app目录下有一个,这两个文件对构建Android Studio项目都起到了至关重要的作用。我面先来看一下最外层的build.gradle文件,代码如下所示


buildscript {

    repositories {

        jcenter()

    }

    dependencies {

        classpath 'com.android.tools.build:gradle:2.2.0'

        files

    }

}

allprojects {

    repositories {

        jcenter()

    }

}

首先两处repositories 的闭包中都声明了jcenter()这行配置,那么这个jcenter是什么意思呢?其实他是一个代码托管仓库,很多Android开源项目都会选择将代码托管到jcenter上,声明这行配置之后,我们就可以在项目中轻松引用任何jcenter上的开源项目了。

接下来,dependencies闭包中使用classpath声明一个Gradle插件。为什么要声明这个插件呢?因为Gradle并不是专门为构建Android项目而开发的,java、C++等很多种项目都可以使用Gradle来构建。这样最外层的build.gradle文件大致分析完了。

接下来我们来看看app目录下的build.gradle文件,代码如下所示


apply plugin: 'com.android.application'

android {

    compileSdkVersion 24

    buildToolsVersion "24.0.2"

    defaultConfig {

        applicationId "com.example.helloworld"

        minSdkVersion 15

        targetSdkVersion 24

        versionCode 1

        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

}

dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {

        exclude group: 'com.android.support', module: 'support-annotations'

    })

    compile 'com.android.support:appcompat-v7:24.2.1'

    testCompile 'junit:junit:4.12'

}

这个相对上面那个要复杂些,我们慢慢来看,首先第一行应用了一个插件,一般有两种值可选:com.android.application 表示这是一个应用程序模块,

com.android.library表示这是一个库模块。应用程序模块和库模块的最大区别在于,一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。

接下来是一个大的android闭包,在这个闭包中我们可以配置项目构建的各种属性,其中,compileSdkVersion用于指定项目的编译版本,这里指定成24表示使用Android7.0系统的SDK编译。buildToolsVersion用于指定项目构建工具的版本,我当前的版本是24.0.2,。

然后我们看到,这里在android闭包中又嵌套了一个defaultConfig闭包defaultConfig闭包中可以对项目的更多细节进行配置。其中,application用于指定项目的包名,minSdkVersion用于指定项目最低兼容的Android系统版本,这里指定成15表示最低兼容到Android4.0系统。目前最新版本为Android8.0targetSdkVersion指定的值表示你在该目标版本上已经做过充分的测试。versionCode用于指定项目的版本号,versionName用于指定项目的版本名。

接下来我们看一下buildTypes闭包buildTypes闭包中用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。另外,debug闭包是可以忽略不写的。release闭包中minifyEnable用于指定是否对项目的代码进行混淆,true表示混淆,false表示不混淆。proguardFiles用于指定混淆时使用的规则文件,这里指定了两个文件,第一个proguard-android.txt是在Android SDK目录下的,里面是所有项目通用的混淆规则,第二个proguard-rules.pro是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。需要注意的是,通过Android Studio直接运行项目生成的都是测试版安装文件。

就还有一个dependencies闭包,这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常Android Studio 项目中一共有3种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或者目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖可以对jcenter库上的开源项目添加依赖关系。我们看一下,dependencies闭包中的配置,第一行的compile fileTree就是一个本地依赖声明,它表示将libs目录下所有的.jar 后缀的文件都添加到项目的构建路径当中。而第二行的compile则是远程依赖声明,com.android.support:appcompat-v7:24.2.1就是一个标准的远程依赖格式,其中com.android.support是域名部分,用于和其他公司的库做区分;appcompat-v7是组名称,用于和同一个公司中不同的库做区分;24.2.1是版本号,用于和同一个库不同的版本做区分。加上这句声明以后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会自动去联网下载,然后再添加到项目的构建路径中。至于库依赖声明这里没有用到,它的基本格式是compile project 后面加上要依赖的库名称,还剩下一句testCompile是用于声明测试用例库的,暂时用不到。

写了这么多相信你也看累了吧,Android Studio默认的字体很小,界面背景为白色,比较的刺眼,所以接下来我们来改一下Android Studio的界面和字体大小,我们点击左上角的File→Settings

[图片上传失败...(image-9e2c1b-1590142086178)]

进入到settings的设置框中,到IDE settings选项列表中"Editor"然后打开Color & Fonts,再点击Font,然后点击Save As创建一个新的字体,当然你也可以和我一样输入new Font。

在这里插入图片描述
在这里插入图片描述

因为你的Scheme里面只有两个属性,Darcula代表黑色代码背景,Default代表默认的白色背景,下面的new Font是我通过点击Save As创建的包含了黑色背景及放大的字体。

这篇博客到这里就写完了,我是初学者-study,有什么问题欢迎发送邮件给我,(==以上内容未使用过Ctrl + C和Ctrl + V,全是一个一个打出来的,图片也都是自己的,第一个图片为白色,是想给你们看一下初始界面的样子,后来我感觉不习惯就有改成黑色的了,码字不易啊,欢迎多多交流==)

QQ邮箱:lonelyholiday@qq.com

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