重写 ViewModelStore
Overriding ViewModelStore
是否可以为 ViewModelProviders
提供一次自己的 ViewModelStore
实现来代替默认实现?
更准确地说,我有兴趣向 ViewModelStore
添加 fun clear(vm: ViewModel)
(或使用索引或类似的东西)功能,以便我可以清除我选择的单个视图模型,而不是只需使用内置 ViewModelStore#clear
:
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
清除所有视图模型。
首先,我认为您 不应该 考虑这样做,因为那是架构组件库的实现细节。由于调整用例以匹配 ViewModel
s API.
暴露的 guidelines/contracts,您很可能应该想出一个更好的解决方案
尽管如此,让我们研究一下这样做的可能性。
这是代码,我们应该使用它来获得 ViewModel
实现:
val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
这段代码的结果是,它会创建一个 HolderFragment
, which is a retained fragment, and will attach it to this
's fragment manager (might be either FragmentActivity
's fragment manager or Fragment
's child fragment manager) 的实例。
此 HolderFragment
将添加一个 HolderFragment.HOLDER_TAG
,因此我们可以从片段管理器中获取此片段的实例。
val holderFragment = supportFragmentManager.findFragmentByTag("android.arch.lifecycle.state.StateProviderHolderFragment") as HolderFragment
它是 HolderFragment
,它创建了 ViewModelStore
和 keeps that instance as a private field 的实例。该字段存在 getter,但不存在 setter,这意味着 "substitute" 此对象的唯一方法是使用反射。
但在此之前,让我们尝试编写 ViewModelStore
class:
的自定义实现
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
包之外调用它。同样,我们可以使用反射来做到这一点(但这有多好?)。
尽管(我)没有建议,但似乎也无法做到(不使用反射)。
是否可以为 ViewModelProviders
提供一次自己的 ViewModelStore
实现来代替默认实现?
更准确地说,我有兴趣向 ViewModelStore
添加 fun clear(vm: ViewModel)
(或使用索引或类似的东西)功能,以便我可以清除我选择的单个视图模型,而不是只需使用内置 ViewModelStore#clear
:
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
清除所有视图模型。
首先,我认为您 不应该 考虑这样做,因为那是架构组件库的实现细节。由于调整用例以匹配 ViewModel
s API.
尽管如此,让我们研究一下这样做的可能性。
这是代码,我们应该使用它来获得 ViewModel
实现:
val viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
这段代码的结果是,它会创建一个 HolderFragment
, which is a retained fragment, and will attach it to this
's fragment manager (might be either FragmentActivity
's fragment manager or Fragment
's child fragment manager) 的实例。
此 HolderFragment
将添加一个 HolderFragment.HOLDER_TAG
,因此我们可以从片段管理器中获取此片段的实例。
val holderFragment = supportFragmentManager.findFragmentByTag("android.arch.lifecycle.state.StateProviderHolderFragment") as HolderFragment
它是 HolderFragment
,它创建了 ViewModelStore
和 keeps that instance as a private field 的实例。该字段存在 getter,但不存在 setter,这意味着 "substitute" 此对象的唯一方法是使用反射。
但在此之前,让我们尝试编写 ViewModelStore
class:
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
包之外调用它。同样,我们可以使用反射来做到这一点(但这有多好?)。
尽管(我)没有建议,但似乎也无法做到(不使用反射)。