查看模型和处理死亡

问题描述 投票:0回答:1

为什么推荐使用 ViewModel 架构组件,如果它不处理 process death?

例如,如果我用 onSaveInstanceState 状况持续 configuration changeprocess deathViewModel 苟延残喘 configuration change为了生存 process death 要从 ViewModel 并同用 onSaveInstanceState 机制。

我错过了什么?

android android-viewmodel
1个回答
3
投票

为什么推荐使用ViewModel架构组件,如果它不处理进程死亡?

我错过了什么?

你是对的,直到2020年1月发生,他们终于发布了。viewmodel-savedstate:1.0.0 然后做了AndroidX活动、碎片和导航最新库版本提供的。SavedStateViewModelFactory 作为默认 ViewModelProvider.Factory.

现在你可以获得一个 SavedStateHandle 进入你 ViewModel 它可以帮助在整个过程中持久地恢复东西。

class MyViewModel(private val savedStateHandle: SavedStateHandle): ViewModel() {
    val someState: MutableLiveData<String> = savedStateHandle.getLiveData("someState")
}

class MyAndroidViewModel(application: Application, private val savedStateHandle: SavedStateHandle): AndroidViewModel(application) {
    val someState: MutableLiveData<String> = savedStateHandle.getLiveData("someState")
}

而这些将 只管工作 通过它们的默认构造函数作为 SavedStateViewModelFactory 通过反射创建它们。

如果你需要一个 SavedStateHandle 和附加参数,那么就不使用默认的 ViewModelProvider.Factory,你可以从 AbstractSavedStateViewModelFactory 会给你 SavedStateHandle 进程死亡时自动恢复。

val viewModel = ViewModelProvider(this, myAbstractSavedStateViewModelFactoryImpl).get(MyViewModel::class.java)

或者使用 KTX 的东西

private val viewModel by viewModels { myAbstractSavedStateViewModelFactoryImpl }

你也可以把ViewModels的范围扩大到Jetpack Navigation的NavGraph上,虽然有点麻烦,但还是可以做到的。

inline fun <reified T : ViewModel> SavedStateRegistryOwner.createAbstractSavedStateViewModelFactory(
    arguments: Bundle,
    crossinline creator: (SavedStateHandle) -> T
): ViewModelProvider.Factory {
    return object : AbstractSavedStateViewModelFactory(this, arguments) {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel?> create(
            key: String, modelClass: Class<T>, handle: SavedStateHandle
        ): T = creator(handle) as T
    }
}

inline fun <reified T : ViewModel> Fragment.navGraphSavedStateViewModels(
    @IdRes navGraphId: Int,
    crossinline creator: (SavedStateHandle) -> T
): Lazy<T> {
    // Wrapped in lazy to not search the NavController each time we want the backStackEntry
    val backStackEntry by lazy { findNavController().getBackStackEntry(navGraphId) }

    return createViewModelLazy(T::class, storeProducer = {
        backStackEntry.viewModelStore
    }, factoryProducer = {
        backStackEntry.createAbstractSavedStateViewModelFactory(
            arguments = backStackEntry.arguments ?: Bundle(), creator = creator
        )
    })
}

然后...

class MyFragment: Fragment() {
    private val mySharedViewModel by navGraphSavedStateViewModels(R.id.registration_graph) { handle ->
        MySharedViewModel(handle)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.