android - ViewModel 和进程死亡

标签 android android-viewmodel

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

例如,如果我用 onSaveInstanceState 保存状态状态持续到 configuration changeprocess death , 而 ViewModel只能生存configuration change , 为了生存 process death需要从 ViewModel 获取状态并使用相同的onSaveInstanceState机制。

我想念什么?

最佳答案

Why it is recommend to use ViewModel architecture component, if it not handle process death?

What do I miss?


你是对的,直到 2020 年 1 月发生,他们终于发布了 viewmodel-savedstate:1.0.0然后使AndroidX Activity、Fragment 和Navigation 最新库版本提供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)
    }
}

关于android - ViewModel 和进程死亡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62342411/

相关文章:

java - 逐帧动画启动画面

java - 使用 facebook 登录 Android 应用程序时出现错误

java - 如何处理不同viewModel之间的通信?

android - 太多的 XML 数据绑定(bind)

java - 如何设置复选框被选中和禁用

java - 来自异步类的多个嵌套回调

Android Hello Map在模拟器上查看问题

android - 使用 ViewModel 的接口(interface)?

android - 从 ViewModel 执行网络操作

android - MVVM中的ExoPlayer