问题
There are two ways that make change value of MutableLiveData
. But what is difference between setValue()
& postValue()
in MutableLiveData
.
I could not find documentation for same.
Here is class MutableLiveData
of Android.
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);
}
}
回答1:
Based on the documentation:
setValue():
Sets the value. If there are active observers, the value will be dispatched to them. This method must be called from the main thread.
postValue():
Posts a task to a main thread to set the given value. If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched.
To summarize, the key difference would be:
setValue()
method must be called from the main thread. But if you need set a value from a background thread, postValue()
should be used.
回答2:
All above answers are correct. But one more important difference. If you call postValue()
on field that has no observers and after that you call getValue()
, you don't receive the value that you set in postValue()
. So be careful if you work in background threads without observers.
回答3:
setValue()
Sets the value. If there are active observers, the value will be dispatched to them.
This method must be called from the main thread.
postValue
If you need set a value from a background thread, you can use
postValue(Object)
Posts a task to a main thread to set the given value.
If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched.
回答4:
setValue()
is called directly from caller thread, and synchronously notifies observers. Also it can be called only from MainThread.postValue()
uses inside something like this new Handler(Looper.mainLooper()).post(() -> setValue())
, so it runs setValue
via Handler
in MainThread. Also it can be called from any thread.
回答5:
setValue()
method must be called from the main thread. If you need set a value from a background thread, you can use postValue()
.
More here .
回答6:
This is not a direct answer to the above problem. The answers from Sagar and w201 are awesome. But a simple rule of thumb I use in ViewModels for MutableLiveData is:
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);
}
Replace mutVal
with your desired value.
来源:https://stackoverflow.com/questions/51299641/difference-of-setvalue-postvalue-in-mutablelivedata