覆盖ViewModelStore

时间:2018-04-09 18:24:47

标签: java android inheritance android-architecture-components android-viewmodel

是否可以提供一次myPassVideoCode = String(chosenWorkout.videoCode) ViewModelStore的自己实现,而不是使用默认值?

更准确地说,我有兴趣将ViewModelProviders(或使用索引或类似的东西)功能添加到fun clear(vm: ViewModel),以便我可以清除我选择的单个视图模型,而不是只需使用内置的ViewModelStore

ViewModelStore#clear

清除所有视图模型。

1 个答案:

答案 0 :(得分:2)

首先,我认为您应该考虑这样做,因为这是架构组件库的实现细节。最有可能的是,您应该通过调整用例来匹配ViewModel API公开的指南/合同,从而提出更好的解决方案。

尽管如此,让我们研究一下这种可能性。

以下是我们应该使用的代码,以便获得ViewModel实现:

val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)

此代码的结果是,它将创建HolderFragment的实例,这是一个保留的片段,并将其附加到this的片段管理器(可能是FragmentActivity的片段管理员或Fragment' s child fragment manager)。

HolderFragment将添加HolderFragment.HOLDER_TAG,因此我们可以从片段管理器中获取此片段的实例。

val holderFragment = supportFragmentManager.findFragmentByTag("android.arch.lifecycle.state.StateProviderHolderFragment") as HolderFragment

它是HolderFragment,它创建了ViewModelStorekeeps that instance as a private field的实例。对于该领域存在一个吸气剂,但是没有一个定位器,这意味着,只有这样才能替代"这个对象是使用反射。

但在此之前,让我们尝试编写ViewModelStore类的自定义实现:

class MyViewModelStore : ViewModelStore() {

  private val mMap = HashMap<String, ViewModel>()

  internal fun put(key: String, viewModel: ViewModel) {
    val oldViewModel = mMap.put(key, viewModel)
    oldViewModel?.onCleared() // COMPILATION ERROR -> Cannot access 'onCleared': it is protected/*protected and package*/ in 'ViewModel'
  }

  internal operator fun get(key: String): ViewModel? {
    return mMap[key]
  }

  override fun clear() {
    for (vm in mMap.values) {
      vm.onCleared() // COMPILATION ERROR -> Cannot access 'onCleared': it is protected/*protected and package*/ in 'ViewModel'
    }
    mMap.clear()
  }

}

不幸的是,我们不能这样做,因为ViewModel#onCleared() has a protected package access,我们无法在android.arch.lifecycle包之外调用它。同样,我们可以使用反射来做到这一点(但这有多好?)。

尽管没有被我建议,但似乎也无法实现(不使用反射)。