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

时间:2019-07-25 07:07:31

标签: android android-architecture-components android-viewmodel android-mvvm

在重新创建活动实例之后,如何重新创建通过ViewModel注入的参数创建的Factory

ViewModel具有如下构造函数:

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

我用factory实例化它:

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

我试图像这样恢复ViewModel,而savedInstanceState不为null(会重新创建活动):

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

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

为,每次通过工厂验证: 我的问题是,我作为MyModel传递给ViewModel的任何东西,以及来自活动Intent的东西,都可能由于用户交互而在以后更改。这意味着,在重新创建时,Intent中的MyModel已经过时,已经存储在ViewModel中,并且受到用户交互的干扰。

3 个答案:

答案 0 :(得分:1)

  

这会导致崩溃,因为没有0参数构造函数   在MyViewModel类中。

由于您没有通过任何工厂来构造ViewModel,它将崩溃。

  

如何重新创建使用通过注入的参数创建的ViewModel   重新创建活动实例后的工厂?

AFAIK ,如果有误,请纠正我,您不必手动在ViewModel上重新创建savedInstanceState。您可以使用viewModel存储活动中使用的数据。因此,在活动重新创建时,ViewModelProvider不会创建viewModel的新实例,但会为您提供旧实例和保存在viewModel中的数据将不会被清除。因此不必担心savedInstanceState

提示:如果要管理工厂的创建并改善娱乐过程。您可以检查this article on ViewModel with Dagger

答案 1 :(得分:0)

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

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

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

根据您的用例或实现,创建repositorymodel的方式基于savedInstanceState的值而变化。

答案 2 :(得分:0)

唯一的答案可能是,无法通过这种方式完成。如果提供了工厂,则必须始终提供它。我不知道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中使用了一个参数构造函数,该参数构造函数始终会占用存储库,但是我移开了模型并仅在重新创建活动时才对其进行设置。