JNI 操作 java 类与对象

jni 操作 java 类

  1. DefineClass

    jclass DefineClass(const char *name, jobject loader, const jbyte* buf,jsize bufLen)
    { return functions->DefineClass(this, name, loader, buf, bufLen); }
    

    从原始类数据的缓冲区加载类;其中 loader 表示类加载器,buf 表示包含 .class 文件数据的缓冲区,bufLen 表示缓冲区长度;

  2. FindClass

    jclass FindClass(const char* name)
    { return functions->FindClass(this, name); }
    

    该函数用于加载本地定义的类;它将搜索由CLASSPATH 环境变量为具有指定名称的类所指定的目录和 zip文件; 其中 name 表示类全名;如果 name 以“[“打头,则返回一个数组类;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        const char* classname = "java/lang/String";
        jclass class_string = env->FindClass(classname);
        if(class_string == NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "FindClass error");
        }else {
            __android_log_print(ANDROID_LOG_INFO, "native", "FindClass success");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  3. GetSuperclass

    jclass GetSuperclass(jclass clazz)
    { return functions->GetSuperclass(this, clazz); }
    

    如果参数 clazz 是任何非 Object 类,返回父类;如果 clazz 是 Object 或接口则返回 NULL;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        const char* classname = "java/lang/String";
        jclass class_string = env->FindClass(classname);
        if(class_string == NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "FindClass error");
        }else {
            __android_log_print(ANDROID_LOG_INFO, "native", "FindClass success");
            jclass class_string_super = env->GetSuperclass(class_string);
            if(class_string_super == NULL){
                __android_log_print(ANDROID_LOG_INFO, "native", "GetSuperclass error");
            }else {
                __android_log_print(ANDROID_LOG_INFO, "native", "GetSuperclass success");
            }
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  4. IsAssignableFrom

    jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
    { return functions->IsAssignableFrom(this, clazz1, clazz2); }
    

    返回参数类 clazz1 是否可以安全转换至参数类 clazz2;

    返回为 true 的三种情况:

    1. 类1 与类 2 为同一类;
    2. 类1 是 类2 的子类;
    3. 类1 实现了 类2 实现的某个接口;
    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        const char* string_class_name = "java/lang/String";
        jclass class_string = env->FindClass(string_class_name);
        const char* object_class_name = "java/lang/Object";
        jclass class_object = env->FindClass(object_class_name);
        jboolean isAssignable = env->IsAssignableFrom(class_string, class_object);
        __android_log_print(ANDROID_LOG_INFO, "native", "isAssignable: %d", isAssignable);
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    

jni 操作 java 对象

  1. AllocObject

    jobject AllocObject(jclass clazz)
    { return functions->AllocObject(this, clazz); }
    

    分配并返回一个新的 java 对象,不调用其任何构造函数,注意 clazz 不能为数组类;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        const char* classname = "java/lang/String";
        jclass class_string = env->FindClass(classname);
    
        jobject string_object = env->AllocObject(class_string);
    
        if (string_object != NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "AllocObject success");
        }else {
            __android_log_print(ANDROID_LOG_INFO, "native", "AllocObject error");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  2. NewObject、NewObjectV、NewObjectA

    jobject NewObject(jclass clazz, jmethodID methodID, ...)
    {
     va_list args;
     va_start(args, methodID);
     jobject result = functions->NewObjectV(this, clazz, methodID, args);
     va_end(args);
     return result;
    }
    
    jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
    { return functions->NewObjectV(this, clazz, methodID, args); }
    
    jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
    { return functions->NewObjectA(this, clazz, methodID, args); }
    

    这三个方法都是用于分配并返回一个新的 java 对象,methodID用于表示其构造方法(后续解释);三个方法的区别在于保存构造方法的参数的方式不一样;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        const char* classname = "java/lang/String";
        jclass class_string = env->FindClass(classname);
        
        jmethodID string_costruct = env->GetMethodID(class_string , "<init>","()V");
        if (string_costruct != NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID success");
        }else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID error");
        }
        
        jobject string_object = env->NewObject(class_string, string_costruct);
        if (string_object != NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "NewObject success");
        }else {
            __android_log_print(ANDROID_LOG_INFO, "native", "NewObject error");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  3. GetObjectClass

    jclass GetObjectClass(jobject obj)
    { return functions->GetObjectClass(this, obj); }
    

    返回 java 对象对应的 java 类

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass thiz_class = env->GetObjectClass(thiz);
        
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  4. GetObjectRefType

    /* added in JNI 1.6 */
    jobjectRefType GetObjectRefType(jobject obj)
    { return functions->GetObjectRefType(this, obj); }
    

    用于返回 java 对象的引用类型, local、global、weak global;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jobjectRefType ref = env->GetObjectRefType(thiz);
        __android_log_print(ANDROID_LOG_INFO, "native", "object ref: %d", ref);
        
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  5. IsInstanceOf

    jboolean IsInstanceOf(jobject obj, jclass obj)
    { return functions->IsInstanceOf(this, obj, clazz); }
    

    返回参数对象 obj 是否参数类 obj 的实例;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        const char* classname = "java/lang/String";
        jclass class_string = env->FindClass(classname);
    
        jboolean isInstanceOf = env->IsInstanceOf(thiz, class_string);
        __android_log_print(ANDROID_LOG_INFO, "native", "isInstanceOf: %d", isInstanceOf);
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  6. IsSameObject

    jboolean IsSameObject(jobject ref1, jobject ref2)
    { return functions->IsSameObject(this, ref1, ref2); }
    

    返回两个对象是否为同一类的实例

jni 操作成员变量

  1. GetFieldID

    jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
    { return functions->GetFieldID(this, clazz, name, sig); }
    

    根据参数中提供的(非静态)成员变量名称,以及成员变量类型返回 field ID;其中 name 表示成员变量名称,sig 表示成员变量的域描述符;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
        jfieldID fid= env->GetFieldID(cls, "s", "Ljava/lang/String;");
        if (fid == NULL) {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetFieldID error");
        } else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetFieldID success");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  2. Get<type>Field

    jobject GetObjectField(jobject obj, jfieldID fieldID)
    { return functions->GetObjectField(this, obj, fieldID); }
    jboolean GetBooleanField(jobject obj, jfieldID fieldID)
    { return functions->GetBooleanField(this, obj, fieldID); }
    jbyte GetByteField(jobject obj, jfieldID fieldID)
    { return functions->GetByteField(this, obj, fieldID); }
    jchar GetCharField(jobject obj, jfieldID fieldID)
    { return functions->GetCharField(this, obj, fieldID); }
    jshort GetShortField(jobject obj, jfieldID fieldID)
    { return functions->GetShortField(this, obj, fieldID); }
    jint GetIntField(jobject obj, jfieldID fieldID)
    { return functions->GetIntField(this, obj, fieldID); }
    jlong GetLongField(jobject obj, jfieldID fieldID)
    { return functions->GetLongField(this, obj, fieldID); }
    __NDK_FPABI__
    jfloat GetFloatField(jobject obj, jfieldID fieldID)
    { return functions->GetFloatField(this, obj, fieldID); }
    __NDK_FPABI__
    jdouble GetDoubleField(jobject obj, jfieldID fieldID)
    { return functions->GetDoubleField(this, obj, fieldID); }
    

    根据参数中的 fieldID 获取参数对象 obj 中的成员变量;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
        jfieldID fid= env->GetFieldID(cls, "s", "Ljava/lang/String;");
        if (fid == NULL) {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetFieldID error");
        } else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetFieldID success");
        }
        jstring jstr = (jstring) env->GetObjectField(thiz, fid);
        const char* str = env->GetStringUTFChars(jstr, NULL);
        __android_log_print(ANDROID_LOG_INFO, "native", "GetObjectField string: %s", str);
        
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  3. Set<type>Filed

    void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
    { functions->SetObjectField(this, obj, fieldID, value); }
    void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
    { functions->SetBooleanField(this, obj, fieldID, value); }
    void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
    { functions->SetByteField(this, obj, fieldID, value); }
    void SetCharField(jobject obj, jfieldID fieldID, jchar value)
    { functions->SetCharField(this, obj, fieldID, value); }
    void SetShortField(jobject obj, jfieldID fieldID, jshort value)
    { functions->SetShortField(this, obj, fieldID, value); }
    void SetIntField(jobject obj, jfieldID fieldID, jint value)
    { functions->SetIntField(this, obj, fieldID, value); }
    void SetLongField(jobject obj, jfieldID fieldID, jlong value)
    { functions->SetLongField(this, obj, fieldID, value); }
    __NDK_FPABI__
    void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
    { functions->SetFloatField(this, obj, fieldID, value); }
    __NDK_FPABI__
    void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
    { functions->SetDoubleField(this, obj, fieldID, value); }
    

    根据参数中的 fieldID 设置参数对象 obj 中的成员变量;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
        jfieldID fid= env->GetFieldID(cls, "s", "Ljava/lang/String;");
        if (fid == NULL) {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetFieldID error");
        } else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetFieldID success");
        }
        jstring jstr = env->NewStringUTF("world");
        env->SetObjectField(thiz, fid, jstr);
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    

jni 操作成员方法

  1. GetMethodID

    jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
    { return functions->GetMethodID(this, clazz, name, sig); }
    

    根据参数中提供的(非静态)成员方法名称,以及方法参数与返回值获取 method ID;其中 name 表示成员方法名称,sig 表示成员方法参数与返回值;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
    
        jmethodID mid = env->GetMethodID(cls, "printString", "()V");
        if (mid == NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID error ");
        }else{
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID success");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  2. Call<type>Method、Call<type>MethodA、Call<type>MethodV

    三个方法都是用于调用对象的成员方法,区别在于方法参数的传入方式不一样,其中<type>用于表示返回值类型;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
    
        jmethodID mid = env->GetMethodID(cls, "printString", "()V");
        if (mid == NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID error ");
        }else{
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID success");
        }
        env->CallVoidMethod(thiz, mid);
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  3. CallNonvirtual<type>Method、CallNonvirtual<type>MethodA、CallNonvirtual<type>MethodV

    这三个方法也是用于调用对象的成员方法,与上述三个方法不同的是:Call<type>Method 是基于对象调用方法,而 CallNonvirtual<type>Method 是基于类调用方法,也就是说 CallNonvirtual<type>Method 可以调用参数对象的父类并非必须当前类;

jni 调用静态成员变量

  1. GetStaticFieldID

    jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
    { return functions->GetStaticFieldID(this, clazz, name, sig); }
    

    根据参数中提供的(静态)成员变量名称,以及成员变量类型返回 field ID;其中 name 表示成员变量名称,sig 表示成员变量的域描述符;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
        jfieldID fid= env->GetStaticFieldID(cls, "s", "Ljava/lang/String;");
        if (fid == NULL) {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetStaticFieldID error");
        } else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetStaticFieldID success");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  2. GetStatic<type>Field

    jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticObjectField(this, clazz, fieldID); }
    jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticBooleanField(this, clazz, fieldID); }
    jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticByteField(this, clazz, fieldID); }
    jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticCharField(this, clazz, fieldID); }
    jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticShortField(this, clazz, fieldID); }
    jint GetStaticIntField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticIntField(this, clazz, fieldID); }
    jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticLongField(this, clazz, fieldID); }
    __NDK_FPABI__
    jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticFloatField(this, clazz, fieldID); }
    __NDK_FPABI__
    jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
    { return functions->GetStaticDoubleField(this, clazz, fieldID); }
    

    根据参数中的 fieldID 获取参数类 clazz 中的成员变量;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
        jfieldID fid= env->GetStaticFieldID(cls, "s", "Ljava/lang/String;");
        if (fid == NULL) {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetStaticFieldID error");
        } else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetStaticFieldID success");
        }
        jstring jstr = (jstring) env->GetStaticObjectField(cls, fid);
        
        const char* str = env->GetStringUTFChars(jstr, NULL);
        __android_log_print(ANDROID_LOG_INFO, "native", "GetStringUTFChars %s", str);
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  3. SetStatic<type>Field

    void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
    { functions->SetStaticObjectField(this, clazz, fieldID, value); }
    void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
    { functions->SetStaticBooleanField(this, clazz, fieldID, value); }
    void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
    { functions->SetStaticByteField(this, clazz, fieldID, value); }
    void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
    { functions->SetStaticCharField(this, clazz, fieldID, value); }
    void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
    { functions->SetStaticShortField(this, clazz, fieldID, value); }
    void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
    { functions->SetStaticIntField(this, clazz, fieldID, value); }
    void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
    { functions->SetStaticLongField(this, clazz, fieldID, value); }
    __NDK_FPABI__
    void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
    { functions->SetStaticFloatField(this, clazz, fieldID, value); }
    __NDK_FPABI__
    void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
    { functions->SetStaticDoubleField(this, clazz, fieldID, value); }
    

    根据参数中的 fieldID 设置参数类 clazz 中的成员变量;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
        jfieldID fid= env->GetStaticFieldID(cls, "s", "Ljava/lang/String;");
        if (fid == NULL) {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetStaticFieldID error");
        } else {
            __android_log_print(ANDROID_LOG_INFO, "native", "GetStaticFieldID success");
        }
        jstring jstr = env->NewStringUTF("world");
        env->SetStaticObjectField(cls, fid, jstr);
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    

jni 操作静态方法

  1. GetStaticMethodID

    jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
    { return functions->GetStaticMethodID(this, clazz, name, sig); }
    

    根据参数中提供的(静态)成员方法名称,以及方法参数与返回值获取 method ID;其中 name 表示成员方法名称,sig 表示成员方法参数与返回值;

    jstring stringFromJNI(JNIEnv *env, jobject thiz){
        __android_log_print(ANDROID_LOG_INFO, "native", "stringFromJNI");
    
        jclass cls = env->GetObjectClass(thiz);
    
        jmethodID mid = env->GetStaticMethodID(cls, "printString", "()V");
        if (mid == NULL){
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID error ");
        }else{
            __android_log_print(ANDROID_LOG_INFO, "native", "GetMethodID success");
        }
    
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  2. CallStatic<type>Method、CallStatic<type>MethodV、CallStatic<type>MethodA

    三个方法都是用于调用类的静态方法,区别在于方法参数的传入方式不一样,其中<type>用于表示返回值类型;

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