SingleLiveEvent 解决livedata接受旧数据

3,237 阅读1分钟
/**
 * A lifecycle-aware observable that sends only new updates after subscription, used for events like
 * navigation and Snackbar messages.
 * <p>
 * This avoids a common problem with events: on configuration change (like rotation) an update
 * can be emitted if the observer is active. This LiveData only calls the observable if there's an
 * explicit call to setValue() or call().
 * <p>
 * Note that only one observer is going to be notified of changes.
 */
public class SingleLiveEvent<T> extends MutableLiveData<T> {

    private static final String TAG = "SingleLiveEvent";

    private final AtomicBoolean mPending = new AtomicBoolean(false);

    @MainThread
    public void observe(LifecycleOwner owner, final Observer<T> observer) {

        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
        }

        // Observe the internal MutableLiveData
        super.observe(owner, new Observer<T>() {
            @Override
            public void onChanged(@Nullable T t) {
                if (mPending.compareAndSet(true, false)) {
                    observer.onChanged(t);
                }
            }
        });
    }

    @MainThread
    public void setValue(@Nullable T t) {
        mPending.set(true);
        super.setValue(t);
    }

    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    public void call() {
        setValue(null);
    }
}

github.com/android/arc…

 利用SingleLiveEvent 使 observe#LiveData时只相应一次onChanged操作

 1 SingleLiveEvent 利用 AtomicBoolean (默认为false)进行赋值,当LiveData 进行 setValue时
 改变 AtomicBoolean的值(set(true))

 2 使用 AtomicBoolean.compareAndSet(true,false)方法,先进行判断(此时的AtomicBoolean的值为true)
   与 compareAndSet设置的except值(第一个参数)比较,因为相等所以将第二个参数设置为AtomicBoolean值设为false
   函数并返回 true ,)

 3 当再次进入该页面虽然 LiveData值并没有改变,仍然触发了 observer方法,由于 AtomicBoolean已经为 false ,但是 except值为 true ,
 与if 进行判断所以 并不会继续触发 onChanged(T)方法

 即只有在 setValue时相应一次onChanged(T)方法。