0

语境

用来MutableLiveData保存一个值。Button点击应该增加值。

问题

MutableLiveData's似乎在用于更改值Observer.onChanged()之前被调用。MutableLiveData.setValue()

例如,在Button点击之前,onChanged日志发生在设置初始值之后(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

单击按钮后(在设置新 val 之前意外onChanged发生日志):

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());
    }
});
4

1 回答 1

0

正如@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");
    }
};

点击后ButtononChanged日志预计发生在之后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是因为onChangedsetValue.

于 2018-09-06T20:10:17.623 回答