[英]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. MutableLiveData
的Observer.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.