savedStateHandle 不保存状态

Ari*_*tro 3 android persistence viewmodel kotlin viewmodel-savedstate

在这个问题之后,我在我的应用程序中做了一些简单的更改,但它没有按我的预期工作。

我有一个计时器,当计时器完成时会发送通知。单击此通知将重新启动活动,删除所有计时器信息,这些信息主要存储在viewModel. 出于这个原因,我决定使用保存的状态viewModel

这是我的viewModel

class TimerViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {

private val _secondsRemaining = savedStateHandle.getLiveData<Long>(SECONDS_REMAINING)
val secondsRemaining : LiveData<Long>
    get() = _secondsRemaining
Run Code Online (Sandbox Code Playgroud)

viewModel这是我在我的中使用的方法Fragment

private val timerViewModel by viewModels<TimerViewModel>()
Run Code Online (Sandbox Code Playgroud)

当我启动计时器时,我会在时钟LiveData的每个滴答声中保存剩余秒数的值。当计时器结束时,应用程序发送通知,计时器再次启动,计算一个新的周期:

timer = object : CountDownTimer(timerLengthSeconds * 1000, 1000){
        override fun onFinish(){
            (....)
        }

        override fun onTick(millisUntilFinished: Long) {
            var secondsRemainingInCountdown = millisUntilFinished / 1000

            (...)

            _secondsRemaining.value = secondsRemainingInCountdown
         
        }
    }.start()
}
Run Code Online (Sandbox Code Playgroud)

因此,当计时器完成时,应用程序会发送通知,但计时器已重新启动,并且剩余的秒数正在更新(我已通过日志检查了这一点)。当用户单击通知时,通知会activity被终止并重新启动,并且期望会看到计时器以及保存在LiveData. 但是当activity重新启动时,LiveData值是空的。

我还尝试将值设置为 10,以防LiveData首次创建时为 null

private val _secondsRemaining = savedStateHandle.getLiveData<Long>(SECONDS_REMAINING, 10)
Run Code Online (Sandbox Code Playgroud)

但是当活动重新启动时,我得到 10 作为 LiveData 的值

我不明白原因。

LiveData我的第二个问题是我想保存存储自定义的 a 的状态class,该状态保存时钟的状态

private val _timerState = MutableLiveData<TimerState>()
val timerState : LiveData<TimerState>
    get() = _timerState
Run Code Online (Sandbox Code Playgroud)

是这样的class

    sealed class TimerState {

    object OnFocusRunning : TimerState()
    object OnRestRunning : TimerState()
    object OnFocusPaused : TimerState()
    object OnRestPaused : TimerState()
    object Completed : TimerState()
    object RestCompleted : TimerState()
    object NotStarted : TimerState()
}
Run Code Online (Sandbox Code Playgroud)

但我在这方面没有成功,因为TimerState它是一种自定义类型class,而不是原始类型。

qkx*_*qkx 6

SavedStateHandle不是很有用。它仅适用于一种特定情况 - 当系统在后台杀死我的应用程序时。

但是,如果用户终止我的应用程序,或清除所有应用程序堆栈,或重新启动其设备怎么办?这些情况即使不是更常见,也是同样常见的情况,并且通常每天都会发生,并且在所有此类情况下SavedStateHandle都无济于事。

我认为官方文档并没有很好地解释这一点,从这个帖子中的评论以及整个 stackoverflow 来看,似乎大多数人都误解了SavedStateHandle。我也是。它不应该用于保存应用程序数据,事实上它只是(暂时)保存会话数据。

由于大多数现实世界的应用程序通常必须覆盖所有上述场景,例如将数据保存在SharedPreferencesorDataStore或中,所以在大多数情况下Room我真的看不出有多少理由需要费心......只需跳过它并使用,你就可以拯救自己时间并保持代码简单。SavedStateHandleSharedPreferences