简体   繁体   English

为什么在进行数据更改之前调用LiveData onChanged?

[英]Why is LiveData onChanged called before data change is made?

Context 上下文

Using MutableLiveData to hold a value. 使用MutableLiveData来保存值。 Button click should increment the value. 单击Button应增加该值。

Problem 问题

MutableLiveData 's Observer.onChanged() appears to be called before MutableLiveData.setValue() is used to change the value. MutableLiveDataObserver.onChanged()在使用MutableLiveData.setValue()更改值之前似乎已被调用。

For example, before Button click, onChanged log happens after initial value is set ( onChanged nanoseconds is greater than new value nanoseconds) . 例如,在单击Button之前, onChanged日志会在设置初始值之后发生( onChanged纳秒大于新值纳秒)。 However, after Button click, onChanged log happens before new value is set ( onChanged nanoseconds is less than new value nanoseconds). 但是,单击Button后, onChanged日志会在设置新值之前发生( onChanged纳秒小于新值纳秒)。 Why does this happen?: 为什么会这样?:

Before Button click ( onChanged log expectedly happens after setting initial val): 在单击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

After Button click ( onChanged log unexpectedly happens before setting new 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

Code

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

As @pskink pointed out, the problem was placement of the log for setting new value, logging before and after the MutableLiveValue.setValue() made it clear: 正如@pskink所指出的那样,问题在于放置用于设置新值的日志,在MutableLiveValue.setValue()明确之前和之后进行记录:

Add before and after logs: 在日志之前和之后添加:

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

After Button click ( onChanged log expectedly happens after setValue ): 单击Button后(预期在setValue之后发生onChanged日志):

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

Edit 编辑

The reason logging after setValue happened after onChanged is because onChanged is called at some point in setValue . onChanged之后发生setValue之后记录日志的原因是因为在setValue中的某个点调用了onChanged

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在LiveData列表中更改值时未调用onChanged? - Why is onChanged not called when value changed in LiveData List? 调用 LiveData onChanged() 方法时,ListAdapter 项呈现错误。 DiffUtil areContentsTheSame() 的可能问题? - ListAdapter items rendered incorrectly when LiveData onChanged() method is called. Possible issue with DiffUtil areContentsTheSame()? 为什么使用setText后两次调用Gtk TextBuffer onChanged? - Why Gtk TextBuffer onChanged is called twice after using setText? 在绘制任何图形之前调用 setVisible 属性 - setVisible property called before any drawing is made LiveData 观察者的 onchanged() 方法执行多次 - LiveData observer's onchanged() method executes several times 实现MapChangeListener的onChanged - 为什么这个lambda - Implementing onChanged of MapChangeListener - why this lambda MVVM MediatorLiveData观察者onchanged多次调用 - MVVM MediatorLiveData observer onchanged called multiple times 当我从屏幕返回时调用 OnChanged ()? - OnChanged () being called when i navigate back from a screen? 为什么@Before不被调用 - Why isn't @Before being called 为什么在设置之前调用构造函数方法 - Why is the constructor method being called before setup
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM