Почему LiveData onChanged вызывается до изменения данных? - PullRequest
0 голосов
/ 06 сентября 2018

Context

Использование MutableLiveData для хранения значения. Button клик должен увеличить значение.

Задача

1013 * s Observer.onChanged(), кажется, вызывается до того, как MutableLiveData.setValue() используется для изменения значения.

Например, перед щелчком Button после установки начального значения происходит запись onChanged log (onChanged наносекунд больше, чем новое значение наносекунд). Однако после нажатия кнопки Button журнал onChanged происходит до установки нового значения (onChanged наносекунд меньше, чем новое значение наносекунд). Почему это происходит?:

До Button нажмите кнопку (onChanged журнал ожидается после установки начального значения):

09-06 20:30:47.877 com.example.android.test D/TAG: initial set val ns 102107899222617
    initial get val ns 102107899367096
09-06 20:30:47.882 com.example.android.test D/TAG: onChanged integer 0 ns 102107903996992

После нажатия кнопки (onChanged log неожиданно происходит до установки нового значения):

09-06 20:30:55.372 com.example.android.test D/TAG: onChanged integer 1 ns 102115394178238
09-06 20:30:55.373 com.example.android.test D/TAG: onClick set new val 1 ns 102115394446415

Код

final MutableLiveData<Integer> val = new MutableLiveData<>();
val.setValue(0); // triggers onChanged
Log.d(TAG, "initial set val ns " + System.nanoTime());

tv.setText("" + val.getValue());
Log.d(TAG, "initial get val ns " + System.nanoTime());

val.observe(this, new Observer<Integer>() {
    @Override
    public void onChanged(@Nullable Integer integer) {
        // onChanged happens after initial setValue but before setValue with new value
        Log.d(TAG, "onChanged integer " + integer + " ns " + System.nanoTime());
        tv.setText("" + integer);
    }
});

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // setting new value (triggers onChanged but 
        // onChanged happens before setting new value via setValue)
        int newVal = val.getValue() + 1;
        val.setValue(newVal);
        Log.d(TAG, "onClick set new val " + newVal + " ns " + System.nanoTime());
    }
});

1 Ответ

0 голосов
/ 06 сентября 2018

Как указывал @pskink, проблема заключалась в размещении журнала для установки нового значения, при ведении журнала до и после того, как MutableLiveValue.setValue() дал понять:

Добавить до и после логов:

final MutableLiveData<Integer> val = new MutableLiveData<Integer>() {
    @Override
    public void setValue(Integer value) {
        Log.d(TAG, "setValue before");
        super.setValue(value);
        Log.d(TAG, "setValue after");
    }
};

После Button клик (onChanged журнал ожидаемо происходит после setValue):

09-06 20:52:02.869 com.example.android.test D/TAG: onClick: before set new val
    setValue before
09-06 20:52:02.870 com.example.android.test D/TAG: onChanged integer 1 ns 103382891472200
    setValue after
    onClick after set new val 1 ns 103382891671576

Редактировать

Причина, по которой запись после setValue произошла после onChanged, заключается в том, что onChanged вызывается в некоторый момент в setValue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...