Istnieją dwa sposoby, aby zmienić wartość MutableLiveData
. Ale jaka jest różnica między setValue()
& postValue()
in MutableLiveData
.
Nie mogłem znaleźć dokumentacji dla tego samego.
Oto klasa MutableLiveData
Androida.
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);
}
}
android
android-livedata
mutablelivedata
Khemraj
źródło
źródło
Wszystkie powyższe odpowiedzi są prawidłowe. Ale jeszcze jedna ważna różnica. Jeśli zadzwonisz
postValue()
na pole, które nie ma obserwatorów, a następnie zadzwoniszgetValue()
, nie otrzymasz wartości, którą ustawiłeśpostValue()
. Dlatego zachowaj ostrożność, jeśli pracujesz w tle bez obserwatorów.źródło
setValue()
jeśli to możliwe, i ostrożnie używać metody „postValue ()” tylko wtedy, gdy jest to konieczne. DziękinoObserveLiveData.postValue("sample")
, w działaniu, kiedy użyłem metody getValue w styluviewModel.noObserveLiveData.getValue
Czy masz na myśli Czy to nie jest wartość, którą ustawiłem w postValue () ("sample")?setValue()
jest wywoływana bezpośrednio z wątku wywołującego, synchronicznie powiadamia obserwatorów iLiveData
natychmiast zmienia wartość. Można go wywołać tylko z MainThread.postValue()
używa wewnątrz czegoś takiegonew Handler(Looper.mainLooper()).post(() -> setValue())
, więc działasetValue
przezHandler
MainThread. Można go wywołać z dowolnego wątku.źródło
setValue()
postValue
źródło
Nie jest to bezpośrednia odpowiedź na powyższy problem. Odpowiedzi udzielone przez Sagar i w201 są niesamowite. Ale prosta zasada, której używam w ViewModels dla MutableLiveData, to:
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); }
Zastąp
mutVal
żądaną wartością.źródło
setValue()
metodę należy wywołać z głównego wątku. Jeśli potrzebujesz ustawić wartość z wątku w tle, możesz użyćpostValue()
.Więcej tutaj .
źródło
W naszej aplikacji użyliśmy pojedynczych danych LiveData, które zawierają dane z wielu widoków na aktywności / ekranie. Zasadniczo N liczba zbiorów danych dla N liczba widoków. Trochę nas to zaniepokoiło, ponieważ sposób, w jaki postData jest przeznaczony. I mamy obiekt stanu w LD, który przekazuje pogląd o tym, który widok należy zaktualizować.
więc LD wygląda tak:
LD { state (view_1, view_2, view_3 …), model_that_contains_data_of_all_views }
Istnieje kilka widoków (widok_1 i widok_2), które musiały zostać zaktualizowane, gdy wystąpi jedno zdarzenie… oznacza, że powinny otrzymać powiadomienie w tym samym czasie, gdy wystąpi zdarzenie. Więc zadzwoniłem:
postData(LD(view_1, data)) postData(LD(view_2, data)
To nie zadziała z powodów, które znamy.
Zrozumiałem, że zasadniczo jeden LD powinien reprezentować tylko jeden pogląd. Wtedy nie ma szans, żebyś musiał wywołać postData () dwa razy z rzędu. Nawet jeśli zadzwonisz, sposób, w jaki postData obsługuje to za Ciebie, jest tym, czego również byś się spodziewał (pokazując najnowsze dane w widoku). Wszystko jest na swoim miejscu.
źródło