ViewModel初始化流程简单理解

本文使用的版本为ViewModel2.6.0-alpha02,API一直在改变,因此要注意下版本。
接上篇,来看看为什么在Activity执行onCreate 之前初始化ViewModel会报错。

 Caused by: java.lang.IllegalStateException: Your activity is not yet attached to the Application instance. You can't request ViewModel before onCreate call.

在理解ViewModel之前,最好对工厂模式有一定的了解。理解设计模式,可以更好地方便理解源码。
可参考这篇,这是我看过的讲设计模式讲的很好的一个博客。
https://blog.csdn.net/LoveLion/article/details/17517213
ViewModel这里用到的是抽象工厂模式。

https://blog.csdn.net/lovelion/article/details/9319181
工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑 将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产。
抽象工厂模式结构

https://blog.csdn.net/lovelion/article/details/9319423

在抽象工厂模式结构图中包含如下几个角色:
● AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
● ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
● AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
● ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

抽象工厂典型代码如下

abstract class AbstractFactory {
  //工厂方法一
  public abstract AbstractProductA createProductA();  
  //工厂方法二 
  public abstract AbstractProductB createProductB(); 
  ……
}

具体工厂类,其典型代码如下

class ConcreteFactory1 extends AbstractFactory {
    //工厂方法一
  public AbstractProductA createProductA() {
    return new ConcreteProductA1();
  }
 
//工厂方法二
  public AbstractProductB createProductB() {
    return new ConcreteProductB1();
  }
 
……
}

ViewModel,这是一个抽象类。可以看做一个抽象产品

//ViewModel
public abstract class ViewModel {
    /**
     * Construct a new ViewModel instance.
     * <p>
     * You should <strong>never</strong> manually construct a ViewModel outside of a
     * {@link ViewModelProvider.Factory}.
     */
    public ViewModel() {
    }
}

当定义一个简单的不带参数的StringViewModel,继承自ViewModel。 这就是一个具体产品

class StringViewModel: ViewModel(){
    var stringLiveData: MutableLiveData<String> = MutableLiveData()

    fun updateStringData(){
        stringLiveData.postValue("AAA")
    }
}

然后调用ViewModelProvider(this).get(StringViewModel::class.java)

class MainActivity : AppCompatActivity() {
    // 使用  Activity 库 提供的 viewModels() 扩展函数
   // private val stringViewModel: StringViewModel by viewModels()
    //错误的写法 这种要写在onCreate里面。或者用var定义,在onCreate中初始化,但是kotlin一般少使用var。
    private val stringViewModel: StringViewModel =  ViewModelProvider(this).get(StringViewModel::class.java)
.....
}

下面分别来看看ViewModelProvider(this)和get(StringViewModel::class.java)。

1.ViewModelProvider(this)

通过调用ViewModelProvider(this),创建ViewModelProvider
调用ViewModelProvider(this)后,走到ViewModelProvider中。调用次构造函数public constructor( owner: ViewModelStoreOwner ),然后调用this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner)),也就是,走到用@JvmOverloads声明的主构造函数constructor( private val store: ViewModelStore, private val factory: Factory, private val defaultCreationExtras: CreationExtras = CreationExtras.Empty, )

// androidx.lifecycle.ViewModelProvider
public open class ViewModelProvider

@JvmOverloads
constructor(
    private val store: ViewModelStore,
    private val factory: Factory,
    private val defaultCreationExtras: CreationExtras = CreationExtras.Empty,
) {
    public interface Factory {
        public fun <T : ViewModel> create(modelClass: Class<T>): T {
            throw UnsupportedOperationException(
                "Factory.create(String) is unsupported.  This Factory requires " +
                    "`CreationExtras` to be passed into `create` method."
            )
        }

        public fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T =
            create(modelClass)
      ...
    }


    public constructor(
        owner: ViewModelStoreOwner
    ) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))

    @MainThread
    public open operator fun <T : ViewModel> get(modelClass: Class<T>): T {
        val canonicalName = modelClass.canonicalName
            ?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels")
        return get("$DEFAULT_KEY:$canonicalName", modelClass)
    }
     ...
    
}

三个参数,第三个参数CreationExtras 默认赋值为CreationExtras.Empty,重点看前两个参数,ViewModelStore和Factory。

    private val store: ViewModelStore,
    private val factory: Factory,
    private val defaultCreationExtras: CreationExtras = CreationExtras.Empty,

1.1 ViewModelStore

ViewModelStore中存在一个HashMap,存储了ViewModel。

public class ViewModelStore {

    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }

    Set<String> keys() {
        return new HashSet<>(mMap.keySet());
    }

    /**
     *  Clears internal storage and notifies ViewModels that they are no longer used.
     */
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
}

由于MainActivity 继承自ComponentActivity,因此调用owner.viewModelStore实际是ComponentActivity中调用getViewModelStore(),最终返回的是mViewModelStore。

// androidx.activity.ComponentActivity
    private ViewModelStore mViewModelStore;

    /**
     * Returns the {@link ViewModelStore} associated with this activity
     * <p>
     * Overriding this method is no longer supported and this method will be made
     * <code>final</code> in a future version of ComponentActivity.
     *
     * @return a {@code ViewModelStore}
     * @throws IllegalStateException if called before the Activity is attached to the Application
     * instance i.e., before onCreate()
     */
// 如果在 Activity 附加到应用程序之前调用 抛出异常,例如 在onCreate()之前。
    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        if (getApplication() == null) {
            throw new IllegalStateException("Your activity is not yet attached to the "
                    + "Application instance. You can't request ViewModel before onCreate call.");
        }
        ensureViewModelStore();
        return mViewModelStore;
    }

    void ensureViewModelStore() {
       ...
       mViewModelStore = new ViewModelStore();
       ...
    }

看到这里,就知道了在 Activity执行onCreate 之前初始化ViewModel为什么会报错 这个问题的答案了。因为getViewModelStore()的时候,判断getApplication() == null,如果为null,就抛出异常
"Your activity is not yet attached to the " + "Application instance. You can't request ViewModel before onCreate call."

// frameworks/base/core/java/android/app/Activity.java

    public final Application getApplication() {
        return mApplication;
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    final void attach(
...
            Application application, Intent intent, 
...) {
        ...
        mToken = token;
        ...
        mApplication = application;
        ...
}
// frameworks/base/core/java/android/app/ActivityThread.java
   /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        ...
            java.lang.ClassLoader cl = appContext.getClassLoader();
//通过反射加载目标Activity,由于我自定义的是MainActivity,所以这里创建了MainActivity。
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
        ...
//创建Application 
        Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
        ...
//调用attach,初始化Activity中的mApplication 
        activity.attach(..., app, ...);
        ...
// 开始执行目标Activity的onCreate()方法回调
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
        ...
    }

//Activity.java
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

     final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...
//由于Java的多态机制,MainActivity(自定义的activity)中重写了onCreate,因此调用的是MainActivity中的onCreate。
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }

Activity启动过程中,调用performLaunchActivity,通过attach,初始化Activity中的mApplication ,调用流程为

performLaunchActivity
->newActivity
->attach
->mInstrumentation.callActivityOnCreate()
->Activity.performCreate()
->MainActivity.onCreate()

最终会回调到了MainActivity(自定义的activity)的onCreate。因此,在onCreate之后,才能确保mApplication 存在。newActivity之后,attach之前,activity中的mApplication 还未初始化。

但是为什么要这样设计?ViewModel用到了mApplication吗?带着这个疑问往下看。

1.2 Factory

ViewModelProvider中定义了一个Factory :public interface Factory,这是抽象工厂。create函数用于创建具体产品

    /**
     * Implementations of `Factory` interface are responsible to instantiate ViewModels.
     */
    public interface Factory {
        /**
         * Creates a new instance of the given `Class`.
         *
         * Default implementation throws [UnsupportedOperationException].
         *
         * @param modelClass a `Class` whose instance is requested
         * @return a newly created ViewModel
         */
        public fun <T : ViewModel> create(modelClass: Class<T>): T {
            throw UnsupportedOperationException(
                "Factory.create(String) is unsupported.  This Factory requires " +
                    "`CreationExtras` to be passed into `create` method."
            )
        }


        public fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T =
            create(modelClass)

        ...
    }

ViewModelProvider源码内部也提供了两个默认Factory实现:NewInstanceFactoryAndroidViewModelFactory,这2个是 具体工厂

1.2.1 defaultFactory(owner)

这里defaultFactory(owner)创建了一个SavedStateViewModelFactory,实际创建了AndroidViewModelFactory,因为ComponentActivity实现了HasDefaultViewModelProviderFactory。

// androidx.lifecycle.ViewModelProvider
    public constructor(
        owner: ViewModelStoreOwner
    ) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))

//ViewModelProvider.AndroidViewModelFactory.Companion#defaultFactory
//获取默认工厂,如果owner实现了HasDefaultViewModelProviderFactory,则用返回defaultViewModelProviderFactory中的工厂,否则用NewInstanceFactory。

            internal fun defaultFactory(owner: ViewModelStoreOwner): Factory =
                if (owner is HasDefaultViewModelProviderFactory)
                    owner.defaultViewModelProviderFactory else instance

instance是NewInstanceFactory。



            /**
             * @suppress
             * Retrieve a singleton instance of NewInstanceFactory.
             *
             * @return A valid [NewInstanceFactory]
             */
            @JvmStatic
            public val instance: NewInstanceFactory
                @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
                get() {
                    if (sInstance == null) {
                        sInstance = NewInstanceFactory()
                    }
                    return sInstance!!
                }

getDefaultViewModelProviderFactory创建了AndroidViewModelFactory。

//androidx.activity.ComponentActivity#getDefaultViewModelProviderFactory
    @NonNull
    @Override
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        if (mDefaultFactory == null) {
            mDefaultFactory = new SavedStateViewModelFactory(
                    getApplication(),
                    this,
                    getIntent() != null ? getIntent().getExtras() : null);
        }
        return mDefaultFactory;
    }
//androidx.lifecycle.SavedStateViewModelFactory
class SavedStateViewModelFactory : ViewModelProvider.OnRequeryFactory, ViewModelProvider.Factory {

    @SuppressLint("LambdaLast")
    constructor(application: Application?, owner: SavedStateRegistryOwner, defaultArgs: Bundle?) {
        ...
        factory = if (application != null) getInstance(application)
            else ViewModelProvider.AndroidViewModelFactory()
    }
}

//ViewModelProvider.AndroidViewModelFactory.Companion#getInstance
            @JvmStatic
            public fun getInstance(application: Application): AndroidViewModelFactory {
                if (sInstance == null) {
                    sInstance = AndroidViewModelFactory(application)
                }
                return sInstance!!
            }

// androidx.lifecycle.ViewModelProvider
        @Suppress("SingletonConstructor")
        public constructor(application: Application) : this(application, 0)

// androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory
    public open class AndroidViewModelFactory
    private constructor(
        private val application: Application?,
        // parameter to avoid clash between constructors with nullable and non-nullable
        // Application
        @Suppress("UNUSED_PARAMETER") unused: Int,
    ) : NewInstanceFactory()

这里需要用到getApplication,因此需要保证getApplication不为null。
这里会创建SavedStateViewModelFactory,这里会创建一个AndroidViewModelFactory。
由于AndroidViewModelFactory继承自 public interface Factory,这里重写了create,当具体工厂需要生产具体产品的时候,会需要调用create,然后就会创建具体产品了,例如AndroidViewModel。

//ViewModelProvider.AndroidViewModelFactory#create
// 调用带Application参数的构造函数创建AndroidViewModel
        @Suppress("DocumentExceptions")
        private fun <T : ViewModel> create(modelClass: Class<T>, app: Application): T {
            return if (AndroidViewModel::class.java.isAssignableFrom(modelClass)) {
                try {
                    modelClass.getConstructor(Application::class.java).newInstance(app)
                } catch (e: NoSuchMethodException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: IllegalAccessException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: InstantiationException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: InvocationTargetException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                }
            } else super.create(modelClass)
        }


//androidx.lifecycle.AndroidViewModel
public class AndroidViewModel extends ViewModel {
    @SuppressLint("StaticFieldLeak")
    private Application mApplication;

    public AndroidViewModel(@NonNull Application application) {
        mApplication = application;
    }

    /**
     * Return the application.
     */
    @SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"})
    @NonNull
    public <T extends Application> T getApplication() {
        return (T) mApplication;
    }
}

2.get(StringViewModel::class.java)

调用get(StringViewModel::class.java)返回了自定义的ViewModel。

// 使用不带参数的ViewModel
class StringViewModel: ViewModel(){
    var stringLiveData: MutableLiveData<String> = MutableLiveData()

    fun updateStringData(){
        stringLiveData.postValue("AAA")
    }
}

// androidx.lifecycle.ViewModelProvider
    @MainThread
    public open operator fun <T : ViewModel> get(modelClass: Class<T>): T {
        val canonicalName = modelClass.canonicalName
            ?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels")
        return get("$DEFAULT_KEY:$canonicalName", modelClass)
    }

    @Suppress("UNCHECKED_CAST")
    @MainThread
    public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
        val viewModel = store[key]
        if (modelClass.isInstance(viewModel)) {
            (factory as? OnRequeryFactory)?.onRequery(viewModel)
            return viewModel as T
        } else {
            @Suppress("ControlFlowWithEmptyBody")
            if (viewModel != null) {
                // TODO: log a warning.
            }
        }
        val extras = MutableCreationExtras(defaultCreationExtras)
        extras[VIEW_MODEL_KEY] = key
        // AGP has some desugaring issues associated with compileOnly dependencies so we need to
        // fall back to the other create method to keep from crashing.
        return try {
            factory.create(modelClass, extras)
        } catch (e: AbstractMethodError) {
            factory.create(modelClass)
        }.also { store.put(key, it) }
    }

这里的参数factory,是前面调用defaultFactory(owner)创建的,也就是AndroidViewModelFactory。最终会走到AndroidViewModelFactory.create

// androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory#create(java.lang.Class<T>, android.app.Application)
        @Suppress("DocumentExceptions")
        private fun <T : ViewModel> create(modelClass: Class<T>, app: Application): T {
//  如果modelClass继承自AndroidViewModel,调用带Application参数的构造函数创建ViewModel对象;
            return if (AndroidViewModel::class.java.isAssignableFrom(modelClass)) {
                try {
                    modelClass.getConstructor(Application::class.java).newInstance(app)
                } catch (e: NoSuchMethodException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: IllegalAccessException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: InstantiationException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: InvocationTargetException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                }
// 否则调用NewInstanceFactory.create
            } else super.create(modelClass)
        }

//androidx.lifecycle.ViewModelProvider.NewInstanceFactory#create
        @Suppress("DocumentExceptions")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return try {
// 直接反射Class对象的无参构造函数来创建ViewModel
                modelClass.newInstance()
            } catch (e: InstantiationException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            } catch (e: IllegalAccessException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            }
        }

由于自定义的StringViewModel,继承自ViewModel。因此最终调用NewInstanceFactory#create,创建了StringViewModel。

get方法简单总结一下就是:

https://segmentfault.com/a/1190000020515580
1.使用ViewModel Class的canonicalName作为ViewModel在ViewModelStore中的唯一标识。
2.通过唯一标识,先查询一下ViewModelStore中是否有该ViewModel对象,如果有则直接返回。
3.如果ViewModelStore中没有该ViewModel对象,则通过Factory工厂类反射创建出ViewModel对象,存入ViewModelStore中,并返回给调用者。

3.带参数的自定义ViewModel初始化流程

前面的代码流程为不带参数的自定义ViewModel初始化流程,现在来看看带参数的自定义ViewModel初始化流程。
初始化的时候,要多加一个参数:StringViewModelWithArg.Factory,并且需要重写getDefaultViewModelCreationExtras,设置CreationExtras 。

// MainActivity.kt

ViewModelProvider(this).get(StringViewModel::class.java) 
ViewModelProvider(this,StringViewModelWithArg.Factory).get(StringViewModelWithArg::class.java)


    override fun getDefaultViewModelCreationExtras(): CreationExtras {
        super.getDefaultViewModelCreationExtras()
        return MutableCreationExtras().apply {
            set(ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY, application)
            set(stringExtraKey, "EEE")
            set(userExtraKey, "FFF")
        }
    }

//com.example.viewmodel.StringViewModelWithArg

   // Define ViewModel factory in a companion object
    companion object {
        val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(
                modelClass: Class<T>,
                extras: CreationExtras
            ): T {
                var string = "string"
                try {
                    string = checkNotNull(extras.get(stringExtraKey))
                }catch (e:Exception){
                    e.printStackTrace()
                }
                return StringViewModelWithArg(string) as T
            }
        }
    }

会走到这里,传入一个自定义的factory,而前面不带参数StringViewModel的初始化使用的是defaultFactory(owner),也就是ComponentActivity中初始化的factory。

// androidx.lifecycle.ViewModelProvider
    public constructor(owner: ViewModelStoreOwner, factory: Factory) : this(
        owner.viewModelStore,
        factory,
        defaultCreationExtras(owner)
    )

然后get(StringViewModelWithArg::class.java)的时候会调用具体工厂的create 去创建具体产品 StringViewModelWithArg。其余里流程一致。

记住工厂模式的4个点:
抽象工厂,具体工厂,抽象产品,具体产品,对应着框架去套,能更好地理解ViewModel初始化流程。

4.初始化简单总结

初始化调用流程简单总结:

调用ViewModelProvider构造函数
->创建ViewModelStore,用来存储ViewModel
->确定具体工厂(传入factory或使用defaultFactory(owner))
->通过ViewModelProvider.get(modelClass)调用具体工厂的create
->生产出具体产品,如StringViewModel,StringViewModelWithArg,
存入ViewModelStore。

一图胜千言,大致可以参考这张图:


https://www.cnblogs.com/mengdd/p/android-creation-of-viewmodel.html

而使用activity扩展库中的viewModels去初始化, 是扩展函数实现了 ViewModelProvider(this).get(StringViewModel::class.java)的功能。

// MainActivity
    private val stringViewModel: StringViewModel by viewModels()
    private val stringViewModel by lazy {
        ViewModelProvider(this).get(StringViewModel::class.java)
    }
// ActivityViewModelLazyKt
@MainThread
public inline fun <reified VM : ViewModel> ComponentActivity.viewModels(
    noinline extrasProducer: (() -> CreationExtras)? = null,
    noinline factoryProducer: (() -> Factory)? = null
): Lazy<VM> {
    val factoryPromise = factoryProducer ?: {
        defaultViewModelProviderFactory
    }

    return ViewModelLazy(
        VM::class,
        { viewModelStore },
        factoryPromise,
        { extrasProducer?.invoke() ?: this.defaultViewModelCreationExtras }
    )
}

通过by,将初始化StringViewModel的任务,委托给了viewModels()。

//ViewModelLazy
                ViewModelProvider(
                    store,
                    factory,
                    extrasProducer()
                ).get(viewModelClass.java).also {
                    cached = it
                }

// androidx.lifecycle.ViewModelProvider
构造函数
public constructor(
        owner: ViewModelStoreOwner
    ) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))
调用get
get(StringViewModel::class.java)

参考链接:
Android源码解析-ViewModel
一文搞懂Android JetPack组件原理之Lifecycle、LiveData、ViewModel与源码分析技巧
ViewModel的创建

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

推荐阅读更多精彩内容