MutableLiveData setValue:Activity 的 onCreate 中的意外行为

Veg*_*gas 5 android android-lifecycle kotlin

我在玩弄 MutableLiveData 的方法来找出什么触发了观察者,什么没有。

现在,我有这个活动:

class ActivityA : AppCompatActivity() {
    private val liveData = MutableLiveData<Int>().apply { this.value = 10 }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        liveData.observe(this, Observer {
            Log.v("ActivityA", "liveData = $it")
        })
        Log.v("ActivityA", "liveData = ${liveData.value}")
        liveData.value = 11
        liveData.postValue(12)
        liveData.value = 13
    }
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

liveData = 10
liveData = 13
liveData = 12
Run Code Online (Sandbox Code Playgroud)

不应该是这个吗?

liveData = 10
liveData = 11
liveData = 13
liveData = 12
Run Code Online (Sandbox Code Playgroud)

mig*_*WOZ 3

你的问题是livedata observer不活跃。因此,当您这样做时liveData.value = 11,该值不会发布到observer. 然后当你liveData.value = 13这样做时overrides做时,值是 11。

要检查您的实时数据是否有任何活跃的观察者,您可以这样做liveData.hasActiveObservers()

文档明确指出,setValue仅在有活跃观察者时才进行调度

无效设置值(T值)

设置值。如果有活跃的观察者,该值将被发送给他们。

但为什么你的观察者不活跃呢?

当您设置一个值时,LiveData内部使用ObserverWrapper's shouldBeActive来检查特定观察者是否处于活动状态。

当您使用observe方法注册您的时observer, 被 observer包装在一个LifecycleBoundObserver( 的子类ObserverWrapper)中,其定义如下shouldBeActive

@Override
boolean shouldBeActive() {
   return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
Run Code Online (Sandbox Code Playgroud)

重要的是 .isAtLeast(STARTED),这里的STARTED类型是Lifecycle.State,其文档有以下说明。

LifecycleOwner 的启动状态。对于 Activity,在两种情况下会达到此状态:

onStart 调用之后;

就在 onPause 调用之前。

因为你注册observeronCreate注册,所以它不会立即激活,因此出现问题。

为了进行验证,您还可以使用observeForever请阅读其文档,它与observe)方法注册您的observer. 因为此方法立即执行observer active,您将看到您期望的输出。

liveData.observeForever {
    Log.v("ActivityA", "liveData = $it")
}
Run Code Online (Sandbox Code Playgroud)