MutableLiveData中setValue()和postValue()的区别

Khe*_*raj 57 android android-livedata mutablelivedata

有两种方法可以改变价值MutableLiveData.但是,什么是区别setValue()postValue()MutableLiveData.

我找不到相同的文档.

这是MutableLiveDataAndroid 类.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Sag*_*gar 103

根据文档:

setValue():

设置值.如果有活动的观察者,则会将值分派给他们.必须从主线程调用此方法.

postValue():

将任务发布到主线程以设置给定值.如果在主线程执行已发布任务之前多次调用此方法,则仅调度最后一个值.

总而言之,关键的区别在于:

setValue()必须从主线程调用方法.但是如果需要从后台线程设置一个值,则postValue()应该使用它.

  • 重要提示:我刚刚注意到,如果您在主线程中并使用 postValue ,则与 setValue 相比,需要多花几毫秒来调度数据。当我手动填充布局时,我遇到了这种情况,使用 setValue 它是即时的,但不是使用 post (3认同)

w20*_*201 53

以上所有答案都是正确的.但是一个更重要的区别.如果您postValue()在没有观察者的字段上调用getValue(),之后调用,则不会收到您设置的值postValue().如果你在没有观察者的后台线程中工作,请小心.

  • 希望我能三连投!基于此,似乎最好尽可能使用“setValue()”,并且仅在必要时谨慎使用“postValue()”。谢谢 (10认同)
  • 不,这没有任何“最好”的方法。如果您从后台线程使用 LiveData,则应该使用 postValue。此外,在最新版本的生命周期组件中,它修复了......可能。 (2认同)

Nil*_*hod 10

setValue()

设置值。如果有活动的观察者,那么值将分派给他们。

必须从主线程调用此方法

postValue

如果需要从后台线程设置值,则可以使用 postValue(Object)

将任务发布到主线程以设置给定值。

如果在主线程执行发布的任务之前多次调用此方法,则只会分派最后一个值。


Him*_*jal 9

这不是上述问题的直接答案。Sagarw201的答案很棒。但是我在 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);
}
Run Code Online (Sandbox Code Playgroud)

替换mutVal为您想要的值。


Lev*_*yan 8

setValue()方法必须从主线程调用。如果需要从后台线程设置值,可以使用postValue().

更多这里


Ufk*_*oku 7

setValue()直接从调用者线程调用,并同步通知观察者。也只能从MainThread调用它。
postValue()使用内这样的事情new Handler(Looper.mainLooper()).post(() -> setValue()),所以它运行setValue通过Handler在MainThread。也可以从任何线程调用它。


tou*_*doy 7

postValue - 可以在任何地方使用

setValue - 仅来自主/UI 线程

基本上,postValue 应该仅在后台线程中使用,因为它可能比反应更快的 setValue 慢。

我写了一个处理这两种情况的代码片段:

/**
 * Live data thread-safe set-value
 * Context: /sf/answers/3655934271/
*/
fun <T> MutableLiveData<T>.assignValue(newValue: T){

    if(Looper.myLooper() == Looper.getMainLooper()) {
        this.value = newValue
    }
    else {
        this.postValue(newValue)
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

TL; DR

  • 如果您在主线程上工作,那么 setValue 和 postValue 将以相同的方式工作,即它们将更新值并通知观察者。
  • 如果在某个后台线程中工作,则不能使用 setValue。你必须在这里与一些观察者一起使用 postValue 。更多这里

  • 不完全是。如果您正在主线程上工作,那么 setValue 和 postValue 有一些区别:setValue 将设置值并立即通知观察者,而 postValue 发布将设置值并稍后通知观察者的任务(通常在几毫秒内) 。 (5认同)