如何在终止应用程序进程之前,在ViewModel的onCleared方法中为SavedStateHandle提供的Liv



在我的个人项目中,我使用Hilt(依赖注入(、SavedStateHandle和ViewModel。

SavedStateHandle,它允许我跨进程死亡保存数据。

因为ViewModel无法在进程死亡时存活,所以我使用Hilt注入在ViewModel内部注入savedStateHandle对象。

当使用协程/viewModelScope来处理http请求时,我使用的是一个自定义类";ViewState";以仅在从UI观察到的一个LiveData中处理多个状态。

例如:LiveData<ViewState<User>>然后在UI中,我绑定viewState:viewMvc.bind(userViewState)

sealed class ViewState<T> : Serializable {
    data class Loading<T>(@Transient val job: Job? = null, val oldResult: T? = null) : ViewState<T>(), Serializable
    data class Fetched<T>(val result: T, val fetchedDate: Date = Date()) : ViewState<T>(), Serializable
    data class Error<T>(val e: Exception, val oldResult: T? = null) : ViewState<T>(), Serializable
    override fun toString(): String {
        return when (this) {
            is Loading -> "ViewState.Loading - oldResult: $oldResult"
            is Fetched -> "ViewState.Fetched - result: $result, fetched date: $fetchedDate"
            is Error -> "ViewState.Error - class: ${e::class.java.simpleName}, message: ${e.localizedMessage?.toString()}"
        }
    }
    fun lastResult(): T? {
        return when (this) {
            is Fetched -> result
            is Loading -> oldResult
            is Error -> oldResult
        }
    }
}

在ViewState.Loading类中,作业是暂时的,因为它不可序列化。在viewModel中使用SavedStateHandle之前,我不需要序列化LiveData值,因为在创建viewModel时,它被初始化为null。

问题是

当用户的viewState为viewState时应用程序进程被终止。正在加载时,viewModelScope不再活动,并且在ViewModel的onCleared((中取消与其关联的作业。

天真地,我认为当;onCleared";事件发生时,我不得不将LiveData的值更改为null或任何我想避免ViewState的值。在进程死亡期间加载值,但显然此时SavedStateHandle已经保存;因为否则,当应用程序状态恢复时,用户视图状态为ViewState.Loading((,我正在等待一些永远不会发生的事情,因为作业已经取消。在序列化SavedStateHandle时,我永远不应该保存ViewState.Loading对象。因此在实践中";工作;变量不应该是瞬态的,因为它永远不会被序列化。

如何截取SavedStateHandle序列化/分组的确切时间以避免此类问题?

我想你不能(除非你自己在Activity/Fragment中保存/恢复(。

然而,您可以在恢复后绕过它,而不是阻止存储Loading状态。例如,当您恢复的状态为Loading时,您可以再次调用Loading函数。

// Inside your viewModel
init{
    if(savedState.contains("Loading)){
        viewModelScope.launch{
            loadData()
        }
    }
}

相关内容

最新更新