Есть два способа изменить значение MutableLiveData
. Но в чем разница между setValue()
& postValue()
in MutableLiveData
.
Мне не удалось найти документацию для этого же.
Вот класс MutableLiveData
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);
}
}
Все ответы верны. Но еще одно важное отличие. Если вы вызываете
postValue()
поле, в котором нет наблюдателей, а после этого вызываетеgetValue()
, вы не получаете значение, которое вы установилиpostValue()
. Так что будьте осторожны, если вы работаете в фоновых потоках без наблюдателей.источник
setValue()
если возможно, и осторожно использовать postValue () только при необходимости. СпасибоnoObserveLiveData.postValue("sample")
действии, когда я использовал getValue, например,viewModel.noObserveLiveData.getValue
Вы имеете в виду Разве это не то значение, которое я установил в postValue () ("sample")?setValue()
вызывается непосредственно из вызывающего потока, синхронно уведомляет наблюдателей иLiveData
немедленно изменяет значение. Его можно вызвать только из MainThread.postValue()
использует внутри что - то вроде этогоnew Handler(Looper.mainLooper()).post(() -> setValue())
, так что он работаетsetValue
черезHandler
в MainThread. Его можно вызвать из любого потока.источник
setValue()
postValue
источник
Это не прямой ответ на указанную выше проблему. Ответы Сагара и 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
желаемым значением.источник
setValue()
метод должен вызываться из основного потока. Если вам нужно установить значение из фонового потока, вы можете использоватьpostValue()
.Подробнее здесь .
источник
В нашем приложении мы использовали одну 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 обработает это за вас, вы также ожидаете (отображение последних данных для вас). Все хорошо встает на свои места.
источник