MutableLiveData setValue: неожиданное поведение в onCreate действия - PullRequest
4 голосов
/ 31 января 2020

Я играю с методами 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
    }
}

Вывод следующее:

liveData = 10
liveData = 13
liveData = 12

Разве это не должно быть?

liveData = 10
liveData = 11
liveData = 13
liveData = 12

1 Ответ

2 голосов
/ 31 января 2020

Ваша проблема в том, что livedata observer не активен . из-за этого, когда вы делаете liveData.value = 11, это значение не публикуется в observer. и впоследствии, когда вы делаете liveData.value = 13 it overrides значение 11.

Чтобы проверить, есть ли у ваших активных данных какие-либо активные наблюдатели, вы можете сделать liveData.hasActiveObservers()

В документах четко указано, что setValue отправляет сообщения только при наличии активных наблюдателей

void setValue (значение T)

Устанавливает значение. Если есть активные наблюдатели, им будет отправлено значение.

Но почему ваш наблюдатель не активен?

Когда вы устанавливаете значение, LiveData внутренне использует ObserverWrapper метод shouldBeActive, чтобы проверить, активен ли указанный c наблюдатель.

и когда вы используете observe метод для регистрации вашего observer, observer оборачивается в LifecycleBoundObserver (подкласс ObserverWrapper), который определяет его shouldBeActive следующим образом.

@Override
boolean shouldBeActive() {
   return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

Значение имеет значение .isAtLeast(STARTED), здесь STARTED имеет тип Lifecycle.State , и его документация имеет следующие чтобы сказать об этом.

Состояние запуска для LifecycleOwner. Для действия это состояние достигается в двух случаях:

после вызова onStart;

непосредственно перед вызовом onPause .

и поскольку вы регистрируете observer в onCreate, он не сразу становится активным и, следовательно, проблема.

Для проверки вы также можно использовать observeForever (, пожалуйста, прочитайте его документацию, он сильно отличается от observe) для регистрации вашего observer. так как этот метод делает observer active мгновенно, вы увидите ожидаемый результат.

liveData.observeForever {
    Log.v("ActivityA", "liveData = $it")
}
...