奇怪的 AndroidViewModel LiveData 观察者行为

nob*_*ial 5 android android-livedata android-viewmodel

我说奇怪是因为我不明白有人可能会告诉我什么正在按预期工作。

我有一个带有 LiveData 成员的 AndroidViewModel,我在 MainActivity 中观察到它来切换一些代码功能。LiveData 对象在视图模型的构造函数中分配初始值。

理论上一切工作正常,除了观察者行为在安装后第一次启动应用程序和随后的应用程序启动之间发生变化。

在安装后第一次启动期间,观察者在我设置后立即被触发,而底层的 LiveData 对象没有被更改。

在应用程序的后续启动期间,观察者不会在设置后过早触发,而是仅在我更改应用程序中其他位置的值时触发,这是我期望发生的情况。

最初我认为观察者以某种方式从 LiveData 初始化中获得延迟触发,但如果这是真的,那么无论是安装后第一次运行还是后续启动,它都应该发生。

因此,为了让应用程序按预期运行,如果应用程序在安装后首次运行,我必须在观察者中使用哨兵,以防止它们在第一次触发期间运行。

有人可以解释为什么会发生这种情况,以及它是否是预期的功能(我不相信),请向我指出解释此问题的文档?

我感觉我又在黑Android了。

下面是人们总是要求的一些代码片段,从 LiveData 声明开始。

@NonNull
private final MutableLiveData<Boolean> consentRequired = new MutableLiveData<>();
Run Code Online (Sandbox Code Playgroud)

ViewModel 构造函数初始化

    setConsentRequired(false);
Run Code Online (Sandbox Code Playgroud)

ViewModel 获取器/设置器

@NonNull
public LiveData<Boolean> getConsentRequired()
{
    return consentRequired;
}
@NonNull
public void setConsentRequired(@NonNull Boolean consentRequired)
{
    this.consentRequired.setValue(consentRequired);
}
Run Code Online (Sandbox Code Playgroud)

观察者

    getViewModel().getConsentRequired().observe(this, item ->
    {
        if (sentryAllowsObserverToRun)
        {
            // Do the observer stuff here
        }
    }
Run Code Online (Sandbox Code Playgroud)

SentryAllowsObserverToRun 是我必须设置的布尔值,以表明这不是安装后首次启动应用程序的第一个触发器。

XII*_*-th 0

问题的答案在此注释中:

...观察者从非活动状态变为活动状态时也会收到更新。此外,如果观察者第二次从非活动状态变为活动状态,则只有当值自上次变为活动状态以来发生更改时,它才会收到更新。

在您的情况下,consentRequired新数据(在 vm 构造函数中分配),当您MainActivity开始观察数据并变得活跃时,consentRequired将数据传递到MainActivity.
为了解决这个问题,您需要避免将临时初始数据设置为LiveData

我想,“关闭应用程序”实际上是指“最小化应用程序”。在这种情况下,应用程序进程保持活动状态,并且活动进入后台状态。在活动保持在倒缝状态之前,视图模型也保留在内存中。当您“重新打开应用程序”时,活动返回前台状态,但文档显示:

此外,如果观察者第二次从非活动状态变为活动状态,则只有当值自上次变为活动状态以来发生更改时,它才会收到更新。

这会导致:当您的 Activity 保留在后台堆栈中并且LiveData的值保持不变时,它将不会接收数据。

您可以在文档的“观察 LiveData 对象”段落中阅读带有示例的详细说明。