Android Studio 目录结构

参考:https://juejin.cn/post/6844903933584883720
参考:https://blog.csdn.net/Deep_rooted/article/details/124764731
参考:https://blog.csdn.net/delete_you/article/details/129126328

顶级结构

1679999088433-3eb8bb45-ad3a-4a9c-9b5e-b37dc9d29d82.png
目录 作用
.gradle 自动生成的,Gradle编译系统,版本由wrapper指定
.idea 自动生成的,Android Studio IDE所需要的文件
gradle 这个目录下包含gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。
.gitignore 上传git 忽略文件
build.gradle 项目的gradle构建脚本,通常是不需要修改的
gradle.properties 这个文件是全局的gradle文件,在这里配置的属性将会影响到项目中所有gradle编译的脚本。
gradlew 用来在命令行界面执行 gradle命令的,gradlew是在Linux和Mac系统使用的
gradlew.bat 用来在命令行界面执行 gradle命令的,gradlew.bat是在Windows系统使用的
local.properties 本地配置,这个文件用于指定android SDK路径,通常是自动生成的,不需要修改
settings.gradle 这个文件用于指定项目中引用的模块

.gitignore

git忽略文件,有些规则,稍微了解一下
#代表是写注释
忽略文件/目录
folderName:直接写名字,代表忽略所有目录和文件,而且会自动搜索多级目录下面的同名文件夹和名录。
folderName/:名字+斜杠结尾,代表忽略目录,不忽略同名的文件。
ps:注意一下,目录和文件的区别,目录就是文件夹,在git不允许空文件夹提交,所以不会有提交一个空文件的情况,而有些文件是没有后缀名的,所以可能出现目录和文件重名的情况。
如下的目录
如果是folder忽略,则是folder目录,以及src/folder 和 src/folder文件都会被忽略。
如果是folder/忽略,则只有folder目录忽略,而src/folder 和 src/folder文件不会被忽略

├── folder
│   └── file1
└── src
    ├── folder
    └── utils
        └── folder

/folderName:斜杠开头表示相对于这个.gitignore所在目录搜索,不会自动搜索多级目录。

!表示取反
!folderName:!代表反向操作,不忽略。

常用通配符
代表通配符,比如.log,代表匹配error.log,logs/debug.log等所有目录下以.log结尾的
代表匹配中间目录,比如src//build,可以匹配到src/test/build,也可以匹配到src/current/build。
?问号匹配 ‘/’外的单个任意字符,比如access?.log将会匹配access0.log,access1.log,accessA.log

gradle.properties

在使用Android Studio新建Android项目之后,在项目根目录下会默认生成一个gradle.properties文件,它是由IDE自动生成的gradle.properties文件。是项目级别的Gradle配置文件,gradle.properties里面定义的属性是全局的,可以在各个模块的build.gradle里面直接引用.我们可以在里面做一些Gradle文件的全局性的配置,也可以将比较私密的信息放在里面,防止泄露。


2.png

常用的的配置

org.gradle.jvmargs=-Xmx5120m -XX:MaxPermSize=1280m -Dfile.encoding=UTF-8
#(JVM堆内存大小,要是想运行的快一些,就改大点,整个8192m啥的)

 
android.useAndroidX=true
# 标识当前 module 启用 Androidx ,当把android项目自动迁移到androidX,
AS会自动在这个文件加上这句

android.enableJetifier=true
# 表示将项目中使用的第三方库也迁移到 Androidx
 
org.gradle.daemon=true
#通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,
#而不是重新 fork 一个 gradle构建进程
 
org.gradle.configureondemand=true 
#按需加载
 
org.gradle.parallel=true 
#并行编译
 
org.gradle.caching=true 
#开启 gradle 缓存
 
android.enableBuildCache=true
#开启依赖缓存,这个设置可以让Android Studio 会把依赖的 jar 或 arr 缓存到本地,并且把模块名称设置为 hash 值。每次编译生成的缓存在 $HOME/.android/build-cache

 
android.injected.testOnly=false
#解决真机无法安装测试包的报错,因为国内一些安卓手机制作商定制的 
#Android 系统不允许安装含带这个属性的测试包。哪怕你使用 -t 参数通过 adb 安装也是不行的,这个很常见
 
android.useNewApkCreator=false
#声明使用旧的打包器解决 Android Studio 升级 3.6 之后,
#报错 Entry name 'AndroidManifest.xml' collided,
#因此禁用新版本打包工具,使用旧的打包工具
 
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.incremental.js=true
#kotlin 增量编译
 
kotlin.caching.enabled=true
#kotlin 编译缓存
 
kotlin.parallel.tasks.in.project=true
#kotlin 并行编译
 
kotlin.code.style=official
# Kotlin code style for this project: "official" or "obsolete"
 
 
# 优化kapt
# 并行运行kapt1.2.60版本以上支持
kapt.use.worker.api=true
# 增量编译 kapt1.3.30版本以上支持
kapt.incremental.apt=true
# kapt avoiding 如果用kapt依赖的内容没有变化,会完全重用编译内容,省掉#`app:kaptGenerateStubsDebugKotlin`的时间
kapt.include.compile.classpath=false
 

build.gradle

旧版本
项目的gradle构建脚本,分为buildscript{},allprojects{},task clean(type: Delete){}这三块

// buildScript gradle的构建脚本
buildscript {
    repositories {
        google()
        mavenCentral()
        jcenter()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    }
    dependencies {
        // 指定gradle插件版本
        classpath "com.android.tools.build:gradle:4.2.2"
    }
}

// allprojects是对所有的项目配置
allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
}

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

  • buildScript:buildscript{}闭包里是gradle脚本执行所需依赖,分别是对应的maven库和插件。

buildscript中的声明是gradle脚本自身需要使用的资源。可以声明的资源包括依赖项、第三方插件、maven 仓库地址等,gradle在执行脚本时,会优先执行buildscript代码块中的内容,然后才会执行剩余的build脚本。

  • repositories:

代表仓库地址,常见参数:
google()“Google官方依赖存储库
mavencentral():由sonatype.org维护的Maven仓库
jcenter():由 bintray.com维护的Maven仓库
maven { url ‘http://maven.aliyun.com/nexus/content/groups/public/}:手动指定Maven仓库地址
JCenter() 与 mavenCenter()在完全不同的服务器上维护,由不同的人提供内容,两者之间毫无关系。在jcenter上有的可能 Maven Central 上没有,反之亦然

  • dependcies:

dependices闭包代表声明下载所需要的依赖,类似maven工程pom.xml中 <dependencies>标签
classpath
添加 buildscript 本身需要的依赖。
implementation
一般是在在模块中的build.gradle中,dependencies 中添加的使应用程序所需要的依赖包,也就是项目运行所需要的东西

  • allprojects:allprojects{}闭包里是项目本身需要的依赖,比如项目所需的maven库。是对所有项目声明的配置
    • repositories

声明所有项目声明的依赖仓库。和buildScript中意思相同。

  • task clean(type: Delete){}:是运行gradle clean时,执行此处定义的task任务,该任务继承自Delete,删除根目录中的build目录。其中buildscript包含repositories闭包和dependencies闭包。

新版本

plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

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

2022年1月的Gradle7.1.0版本做的更新,如果你用的是小蜜蜂版本的Android Studio,创建的的项目,默认就是没有buildscript和allprojects的,之前的仓库配置被挪到Project下的setting.gradle里面了。
如果确实还是需要旧版本的buildscript{}内容,还是可以使用,放在plugins{}上面即可,例如

buildscript {
    dependencies {
        classpath 'com.yanzhenjie.andserver:plugin:2.1.10'
    }
}

plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

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

local.properties

sdk.dir=AppData\Local\Android\Sdk
本地配置,这个文件用于指定android SDK路径,通常是自动生成的,不需要修改

seetings.gradle

存放于项目根目录下,此设置文件会定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内

// 依赖管理
// 定义远程或者本地仓库位置,gradle将会从这些仓库搜索并下载对应依赖以及相关内容
pluginManagement {

    // 定义仓库
    repositories {
        gradlePluginPortal()
        google()                // google官方仓库
        mavenCentral()          // maven中心仓库,替代老版本的JCenter
    }

    // 定义解决方案,即对所下载的依赖做出的处理
    resolutionStrategy{
        eachPlugin{
            if (requested.id.id == 'dagger.hilt.android.plugin'){
                useModule("com.google.dagger:hilt-android-gradle-plugin:2.38.1")
            }
        }
    }
}

// 定义所有模块的仓库位置
// 这是一项全局配置,对于单个模块仍然需要定义自己的build.gradle来设置!
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

// 根工程名称(即你创建该android项目时的名字)
rootProject.name = "Character"
// 定义模块目录所在位置
include ':app'

rootProject:配置的是当前的工程名
include:引用不同的moulde

moudle(App)目录

3.png
目录 作用
buidl 编译时生成
libs 存放第三方的jar包
release 存放打包文件,需要打包完成才有的文件夹
src module源码所在目录
.gitignore git源码管理文件
proguard-rules.pro 指定代码混淆
build.gradle app模块的gradle构建脚本
app.iml intellij IDEA项目都会自动生成的,AS是基于IDEA开发的

build

和外层的build类似主要包含编译时自动生成的内容,其中在outputs文件夹下存放打包好的apk文件

libs

如果项目中是用了第三方的jar包,就需要把jar包放到libs目录下,然后jar包会被自动添加到构建路径(如集成百度地图sdk,把jar包放到libs目录。可以在build.gradle(app)文件中查看当前项目依赖)

release

存放打包文件,需要打包操作之后,选择路径才会生成

.gitignore

git源码管理文件,同最外层一样

proguard-rules.pro

指定混淆规则,需要和module的build.gradle里面android{}闭包里面buildTypes{}配合使用,是否打开混淆。(目前没有使用需求,后续补充)

build.gradle:

app模块的gradle构建脚本,总共有三块


4.png

apply:声明是Android程序
android:android{}闭包,这个闭包主要为了配置项目构建的各种属性
dependecies:dependencies{}闭包,该闭包定义了项目的依赖关系,一般项目都有三种依赖方式:本地依赖、库依赖和远程依赖。
大概build.gradle构建脚本如下

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 33  // 编译Android工程的SDK版本
    buildToolsVersion "33.0.0" // 构建Android工程所用的构建工具版本,Android Studio3.0后去除此项配置
        
    defaultConfig {
        applicationId "com.example.gradle_lifecycle"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false //是否启用混淆
            // 混淆文件
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    //自动化打包配置
    signingConfigs {// 自动化打包配置
            release {// 线上环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
            debug {// 开发环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
        }
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // implemengtation 添加的使应用程序所需要的依赖包
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation project(':mylibrary')
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
  • plugins{}:一般有两种值可选:

com.android.application 表示这是一个应用程序模块。可以直接运行。
com.android.library 表示这是一个库模块,只能作为代码库依附于别的应用程序模块来运行,打包得到的是.aar文件

  • android{}:android{}是Android Gradle插件提供的一个扩展类型,可以让我们自定义Android Gradle工程。
    • compileSdkVersion:编译Android工程的SDK版本
    • buildToolsVersion “23.0.1”:构建Android工程所用的构建工具版本
    • defaultConfig{}:defaultConfig{}是默认的配置,是一个ProductFlavor(构建渠道),ProductFlavor允许我们根据不同的情况同时生成不同的APK包。defaultConfig闭包可以对项目的更多细节进行配置。
defaultConfig {
        applicationId "com.example.gradle_lifecycle"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
  - **applicationId** :应用ID,在Android设备和市场上,这个ID是你应用的唯一标识。不是包名,默认和包名一致。
  - **midSdkVersion:**用于指定项目最低兼容的Android系统版本。midSdkVersion 21对应Android 5.0。表示安装应用程序的手机系统的版本必须要>=5.0
  - **targetSdkVersion:**APP所使用这个所设定的版本及该版本前的所有特性。如果设置为22,那么23以及23以后的所有新特性、新功能和API新行为统统无视;只认识22以及22之前提供的功能和API行为。
  - **versionCodeApp:**应用内部版本名称,自己看的,用来给设备程序识别版本。
  - **versionNameAPP:**应用的版本名称。展示给消费者的版本号,代表应用程序的版本信息。
  • buildTypes{}:生产/测试环境配置。
buildTypes {// 生产/测试环境配置
        release {// 生产环境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", ""https://release.cn/"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.release//设置签名信息
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
        debug {// 测试环境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", ""https://test.com/"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.debug//设置签名信息
            debuggable false//是否支持断点调试
            jniDebuggable false//是否可以调试NDK代码
            renderscriptDebuggable false//是否开启渲染脚本就是一些c写的渲染方法
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
    }
  - **release {}:** 生产环境
     - **minifyEnabled**:表明是否对代码进行混淆,true表示对代码进行混淆,false表示对代码不进行混淆,默认的是false。
     - **proguardFiles**:指定混淆的规则文件,这里指定了proguard-android.txt文件和proguard-rules.pro文件两个文件,proguard-android.txt文件为默认的混淆文件,里面定义了一些通用的混淆规则。proguard-rules.pro文件位于当前项目的根目录下,可以在该文件中定义一些项目特有的混淆规则。
     - **buildConfigField**:用于解决Beta版本服务和Release版本服务地址不同或者一些Log打印需求控制的。例如:配置buildConfigField("boolean", "LOG_DEBUG", "true"),这个方法接收三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值,调用的时候BuildConfig.LOG_DEBUG即可调用。
     - **debuggable**:表示是否支持断点调试,release默认为false,debug默认为true。
     - **jniDebuggable**:表示是否可以调试NDK代码,使用lldb进行c和c++代码调试,release默认为false
     - **signingConfig**:设置签名信息,通过signingConfigs.release或者signingConfigs.debug,配置相应的签名,但是添加此配置前必须先添加signingConfigs闭包,添加相应的签名信息。
     - **renderscriptDebuggable**:表示是否开启渲染脚本就是一些c写的渲染方法,默认为false。
     - **renderscriptOptimLevel**:表示渲染等级,默认是3。
     - **pseudoLocalesEnabled**:是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多。
     - **applicationIdSuffix**:和defaultConfig中配置是一的,这里是在applicationId 中添加了一个后缀,一般使用的不多。
     - **versionNameSuffix**:表示添加版本名称的后缀,一般使用的不多。
     - **zipAlignEnabled**:表示是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率,release和debug默认都为true。
  - **debug {}:**开发环境,关键参数同生产环境
  • signingConfigs{}:自动化打包配置
    signingConfigs {// 自动化打包配置
            release {// 线上环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
            debug {// 开发环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
        }
  - **release {}:**线上环境
     - keyAlias 'test':关键别名
     - keyPassword '123456' :关键别名密码
     - storeFile file('test.keystore') :位置
     - storePassword '123456' //密码
  - **debug {}:**开发环境,同线上环境
  • sourceSets{}:配置目录指向
    • 配置 jniLibs.srcDirs = ['libs'],可以在Android studio的Android视图下生成jniLibs文件夹,可以方便我们存放jar包和库文件,其中Android视图下的jniLibs和project视图下的libs指向同一文件夹(app→libs),如下图所示:
sourceSets {//目录指向配置 
    main {
    jniLibs.srcDirs = ['libs']//指定lib库目录 
  } 
}
  • packagingOptions{}闭包:打包时的相关配置,当项目中依赖的第三方库越来越多时,有可能会出现两个依赖库中存在同一个(名称)文件。如果这样,Gradle在打包时就会提示错误(警告)。那么就可以根据提示,然后使用以下方法将重复的文件剔除,比较常用的是通过exclude去除重复的文件,例如:
packagingOptions{
        //pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
        // 表示当apk中有重复的META-INF目录下有重复的LICENSE文件时 只用第一个 这样打包就不会报错
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
        //这个是有默认值得 merges = [] 这样会把默默认值去掉 所以我们用下面这种方式 在默认值后添加
        merge 'META-INF/LICENSE'

        //这个是在同时使用butterknife、dagger2做的一个处理。同理,遇到类似的问题,只要根据gradle的提示,做类似处理即可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

  • productFlavors{}:多个渠道配置这个配置是经常会使用到的,通常在适配多个渠道的时候,需要为特定的渠道做部分特殊的处理,比如设置不同的包名、应用名等。场景:当我们使用友盟统计时,通常需要设置一个渠道ID,那么我们就可以利用productFlavors来生成对应渠道信息的包,如:
productFlavors {
        wandoujia {
            //豌豆荚渠道包配置
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
            //manifestPlaceholders的使用在后续章节(AndroidManifest里的占位符)中介绍
        }
        xiaomi {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
            applicationId "com.wiky.gradle.xiaomi" //配置包名

        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        //...
    } 
  • lintOptions{}:代码扫描分析,Lint 是Android Studio 提供的 代码扫描分析工具,它可以帮助我们发现代码结构/质量问题,同时提供一些解决方案,而且这个过程不需要我们手写测试用例。Lint 发现的每个问题都有描述信息和等级(和测试发现 bug 很相似),我们可以很方便地定位问题,同时按照严重程度进行解决。
    //程序在编译的时候会检查lint,有任何错误提示会停止build,我们可以关闭这个开关
    lintOptions {
        abortOnError false //即使报错也不会停止打包
        checkReleaseBuilds false  //打包release版本的时候进行检测
    }

  • dependcies{}:该闭包定义了项目的依赖关系,一般项目都有三种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖可以对jcener库上的开源项目添加依赖关系。
    • 从Android Studio3.0后compile引入库不在使用,而是通过api和implementation,api完全等同于以前的compile,用api引入的库整个项目都可以使用,用implementation引入的库只有对应的Module能使用,其他Module不能使用,由于之前的项目统一用compile依赖,导致的情况就是模块耦合性太高,不利于项目拆解,使用implementation之后虽然使用起来复杂了但是做到降低偶合兴提高安全性。
dependencies {//项目的依赖关系
    implementation fileTree(include: ['*.jar'], dir: 'libs')//本地jar包依赖
    implementation 'com.android.support:appcompat-v7:27.1.1'//远程依赖
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'//声明测试用例库
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  • implementation fileTree(include: ['*.jar'], dir: 'libs'):implementation fileTree是一个本地依赖声明,表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。
  • implementation 'com.android.support:appcompat-v7:27.1.1':implementation语句为 远程依赖声明,'com.android.support:appcompat-v7:27.1.1'为一个标准的远程依赖库格式,其中com.android.support为域名部分,用于区分不同公司的库;appcompat-v7为组件名称,用于区分同一个公司的不同库;27.1.1为版本号,用于区分同一个库的不同版本。加上这句声明后,Gradle在构建项目时会先检查一下本地是否已经缓存过该库,若没有缓存则自动联网下载,下载后自动添加到项目的构建路径中去。
  • testImplementation和androidTestImplementation:表示声明测试用例库。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容