使用LiveData处理事件

Posted potato-eater

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用LiveData处理事件相关的知识,希望对你有一定的参考价值。

今天遇到了一件奇怪的事情,在同事手机上有个Activity(A)关闭后竟然又被创建了,调试后发现原来每次关闭这个Activity(A)都会触发上一个Activity(B)的生命周期改变,然后在订阅的LiveData对象会收到OnChange消息创建Activity(A),正常情况下,这种数据我们只需要处理一次,准确的来讲就是事件,这种情况下我们可以使用下面的SingleLiveEvent来处理。

package com.example.android.architecture.blueprints.todoapp;
 
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Observer;
import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.util.Log;
 
import java.util.concurrent.atomic.AtomicBoolean;
 
/**
 * 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);
    }
}

 

以上是关于使用LiveData处理事件的主要内容,如果未能解决你的问题,请参考以下文章

Android LiveData防止在观察时接收到最后一个值

在我旋转屏幕之前,LiveData 不会加载到片段中

使用 ViewModel 和 LiveData 递增变量的简单片段示例 - 变量始终为空

Android MVVM:具有多个片段的活动 - 将共享 LiveData 放在哪里?

LiveData 没有观察具有共享视图模型的子视图页面片段

可以在服务中使用 LiveData 对象吗?