奇怪的AndroidViewModel LiveData观察者行为

时间:2018-10-23 13:58:44

标签: android android-livedata android-viewmodel

我之所以说怪异,是因为我不明白有人可能会告诉我我的工作按预期进行。

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

除了观察者的行为在安装后第一次启动应用程序以及随后启动应用程序之间发生变化之外,所有的理论上都可以正常运行。

在安装后的首次启动期间,设置我的观察者会立即触发,而不会更改底层LiveData对象。

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

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

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

有人可以解释为什么会发生这种情况吗?如果我不相信这是预期的功能,请向我介绍解释此问题的文档?

我觉得我正在再次入侵Android。

这里有一些代码片段,人们总是从LiveData声明开始要求它们。

@NonNull
private final MutableLiveData<Boolean> consentRequired = new MutableLiveData<>();

ViewModel构造函数初始化

    setConsentRequired(false);

ViewModel getter / setter

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

观察者

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

sentryAllowsObserverToRun是我必须设置为布尔值的布尔值,它不是安装后首次启动应用程序的第一个触发器。

1 个答案:

答案 0 :(得分:0)

问题的答案位于此注释中:

  

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

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

我想,“关闭申请”实际上是指“最小化申请”。在这种情况下,应用程序进程仍处于活动状态,并且活动进入后台状态。在活动保留在回溯中之前,viewmodel也保留在内存中。当您“重新打开应用程序”时,活动返回到前台状态,但是文档说:

  

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

这导致:您的活动保留在后退堆栈中并且LiveData的值保持不变时将不会接收数据。

您可以在文档的Observe LiveData objects段落中阅读带有示例的详细说明。