有两种方法可以更改MutableLiveData
的值。但是在setValue()
中 postValue()
和 MutableLiveData
有什么区别。
我找不到相同的文档。
这是Android的MutableLiveData
类。
package android.arch.lifecycle;
/**
* {@link LiveData} which publicly exposes {@link #setValue(T)} and {@link #postValue(T)} method.
*
* @param <T> The type of data hold by this instance
*/
@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
答案 0 :(得分:51)
基于文档:
设置值。如果有活跃的观察者,则该值为 派给他们。必须从主线程调用此方法。
将任务发布到主线程以设置给定值。如果您在主线程执行发布的任务之前多次调用此方法,则只会分派最后一个值。
总而言之,关键区别在于:
setValue()
方法必须从主线程调用。但是,如果需要从后台线程设置值,则应使用postValue()
。
答案 1 :(得分:28)
以上所有答案均正确。但是还有一个重要的区别。如果您在没有观察者的字段上调用postValue()
,然后再调用getValue()
,则不会收到在postValue()
中设置的值。因此,如果您在没有观察员的情况下使用后台线程,请当心。
答案 2 :(得分:6)
设置值。如果有活动的观察者,那么值将分派给他们。
必须从主线程调用此方法。
如果您需要通过后台线程设置值,则可以使用
postValue(Object)
将任务发布到主线程以设置给定值。
如果您在主线程执行发布的任务之前多次调用此方法,则只会分派最后一个值。
答案 3 :(得分:6)
setValue()
直接从调用者线程中调用,并同步通知观察者。也只能从MainThread调用。
postValue()
在类似new Handler(Looper.mainLooper()).post(() -> setValue())
的内部使用,因此它通过MainThread中的setValue
运行Handler
。也可以从任何线程调用它。
答案 4 :(得分:3)
setValue()
方法必须从主线程调用。如果需要从后台线程设置值,则可以使用postValue()
。
更多here。
答案 5 :(得分:1)
这不是上述问题的直接答案。来自Sagar和w201的答案很棒。但是我在ViewModels中使用MutableLiveData的简单经验法则是:
private boolean isMainThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
private MutableLiveData<Boolean> mutVal = new MutableLiveData<>(false);
public LiveData<Boolean> getMutVal() { return this.mutVal; }
public void setMutVal(boolean val) {
if (isMainThread()) mutVal.setValue(val);
else mutVal.postValue(val);
}
将mutVal
替换为所需的值。
答案 6 :(得分:1)
TL;博士
答案 7 :(得分:0)
在我们的应用中,我们使用了单个LiveData,其中包含活动/屏幕中多个视图的数据。对于N个视图,基本上没有N个数据集。这有点困扰我们,因为postData的设计方式。并且在LD中有状态对象,可以传达有关需要更新哪个视图的视图。
所以LD看起来像这样:
LD {
state (view_1, view_2, view_3 …),
model_that_contains_data_of_all_views
}
有两个视图(view_1和view_2)在一个事件发生时必须更新。.意味着它们应该在事件发生的同时通知。所以,我打电话给了:
postData(LD(view_1, data))
postData(LD(view_2, data)
由于我们所知道的原因,这行不通。
据我了解,基本上一个LD应该只代表一个视图。这样就没有机会连续两次调用postData()了。即使调用,postData为您处理数据的方式也将是您期望的(在视图中显示最新数据)。一切都准备就绪。
一个LD->一个视图。 完美
一个LD->多个视图可能会有奇怪的行为