尝试在没有工厂的情况下重新创建时 ViewModel 崩溃

ViewModel crashing while trying to recreate without factory

如何在重新创建 activity 实例后重新创建使用通过 Factory 注入的参数创建的 ViewModel

ViewModel 有一个这样的构造函数:

class MyViewModel(
        val model: MyModel,
        val repository: MyRepository
) : ViewModel()

我用工厂实例化它:

ViewModelProviders
                    .of(this, MyViewModelFactory(
                            model = MyModel()
                            repository = MyRepository()))
                    .get(MyViewModel::class.java)

我试图像这样恢复 ViewModel,而 savedInstanceState 不为空(重新创建 activity):

ViewModelProviders
                    .of(this)
                    .get(MyViewModel::class.java)

这会导致崩溃,因为 no 0 arguments constructor 存在于 MyViewModel class 中。

如,每次过厂: 我的问题是,无论我作为 MyModel 传递给 ViewModel,以及来自 activity Intent 的任何内容,稍后可能会因用户交互而改变。这意味着,在重新创建时,Intent 中的 MyModel 对于已存储在 ViewModel 中并被用户交互篡改的模型已经过时。

This causes a crash because no 0 arguments constructor is present inside MyViewModel class.

它会崩溃,因为你没有通过任何工厂来构建 ViewModel

How to recreate ViewModel that was created with params injected via Factory after instance of activity is recreated?

AFAIK,您不必在 savedInstanceState 上手动重新创建 ViewModel。您可以使用 viewModel 存储 activity.So 中使用的数据,在重新创建 activity 时,ViewModelProvider 不会创建 [=13= 的新实例] 但会给你旧实例并且 viewModel 中保存的数据不会 cleared.So 无需担心 savedInstanceState.

提示:如果您想管理工厂的创建并改进游戏过程。你可以查看 this article on ViewModel with Dagger

MyViewModel 中没有 0 个参数的构造函数。当您尝试在不提供 Factory 的情况下获取 ViewModel 的实例时,它将查找 0 参数构造函数。

无论 savedInstanceState 是否为 null,您都可以使用它。

ViewModelProviders
                    .of(this, MyViewModelFactory(
                            model,repository))
                    .get(MyViewModel::class.java)

而是创建 repositorymodel 的方式会根据 savedInstanceState 值发生变化,具体取决于您的用例或实施方式。

可能唯一的答案是,不能这样做。如果提供了工厂,则必须始终提供。我不知道 ViewModel 娱乐背后的机制,但这些并不像我希望的那样聪明。

我当前的实现如下所示:

    viewModel = ViewModelProviders
            .of(this, MyFactory(MyRepository()))
            .get(MyMViewModel::class.java)

    val binding = DataBindingUtil.setContentView<ActivityCreateFoodstuffBinding>(this, R.layout.my_activity)
    binding.viewModel = viewModel

    if (savedInstanceState == null) {
        val model = intent.getParcelableExtra<MyModel>("model")
        viewModel.model.set(model)
    }

我在 ViewModel 中使用了一个总是占用存储库的参数构造函数,但是我移开了模型并仅在新创建 activity 时才设置它。