LiveData的工作原理分析

文章目录

  • 一、简介
  • 二、数据监听源码分析
    • 2.1 LiveData的observer方法分析
    • 2.2 LifecycleBoundObserver源码分析
    • 2.3 ObserverWrapper源码分析
    • 2.4 LifecycleEventObserver接口分析
  • 三、数据发送源码分析
    • 3.1 LiveData的postValue/setValue方法分析
    • 3.2 LiveData的dispatchingValue方法分析
    • 3.3 LiveData的considerNotify方法分析
  • 四、LiveData的粘性事件
    • 4.1 何为粘性事件
    • 4.2 发生粘性事件的原因
    • 4.3 从源码角度分析粘性事件
    • 4.4 如何避免粘性事件

一、简介

LiveData是一个数据持有类,它可以通过添加观察者被其他组件观察其变更。不同于普通的观察者,它最重要的特性就是遵从应用程序的生命周期,如在Activity中如果数据更新了但Activity已经是destroy状态,LivaeData就不会通知Activity(observer)。当然LiveData的优点还有很多,如不会造成内存泄漏等。LiveData通常会配合ViewModel来使用,ViewModel负责触发数据的更新,更新会通知到LiveData,然后LiveData再通知活跃状态的观察者。

二、数据监听源码分析

2.1 LiveData的observer方法分析

直接从observe方法入手

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    // 判断是否在主线程,不是则报错
    assertMainThread("observe");
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore 如果Activity/fragment已经销毁了,那么忽略
        return;
    }
     // 重点代码,包装了一个LifecycleBoundObserver,将外部出入的owner和observer封装了一层
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    // 重点代码,mObservers=SafeIterableMap, ObserverWrapper>,可以把它看作Map
    // 这里的目的就是尝试保存到map,返回值可以用来判断是第一次添加还是说之前已经添加过
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && !existing.isAttachedTo(owner)) {
        // 如果返回值存在,那么说明不是第一次put到Map缓存中,那么避免重复添加,这里直接抛出异常了
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        // 已经添加过观察者,直接返回
        return;
    }
    // 如果owner没有添加过观察者,那么才添加,注意这里添加的并不是我们外面传入的,而已经过包装过后的LifecycleBoundObserver
    // 当添加了Lifecycle的观察者后,LifecycleBoundObserver就能感知owner的生命周期了
    owner.getLifecycle().addObserver(wrapper);
}

2.2 LifecycleBoundObserver源码分析

下面就来看看LifecycleBoundObserver到底是何方神圣

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
    @NonNull
    final LifecycleOwner mOwner; // 真正的外部传入的LifecycleOwner

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer); // 这里将外部传入的观察者传给了父类ObserverWrapper
        mOwner = owner;
    }

    @Override
    boolean shouldBeActive() {
        // 这里状态要start之后才表示激活了
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    // 实现GenericLifecycleObserver的接口方法,由LifeCycler回调
    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            // 当目标不可见的时候调用liveData的removeObserver方法,将外部传入的观察者移除掉
            removeObserver(mObserver);
            return;
        }
        // 重点代码:通知父类ObserverWrapper状态变化,后面会介绍
        activeStateChanged(shouldBeActive());
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        // 是否添加到目标owner中
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
        // 目标lifeCycle异常观察者,注意传入的是this,也就是包装后的
        mOwner.getLifecycle().removeObserver(this);
    }
}

上面代码并不多,LifecycleBoundObserver 继承自LiveData的内部类ObserverWrapper 并实现了 GenericLifecycleObserver接口,而 GenericLifecycleObserver 接口又继承自 LifecycleObserver 接口,那么根据 Lifecycle 的特性,实现了LifecycleObserver接口并且加入 LifecycleOwner 的观察者里就可以感知或主动获取 LifecycleOwner 的状态。

2.3 ObserverWrapper源码分析

我们来看看ObserverWrapper源码

// 这是定义在LiveData内部的抽象类
private abstract class ObserverWrapper {
    // 这里的观察者其实就是我们外面传入的,也就是它的子类LifecycleBoundObserver的构造方法赋值的
    final Observer<? super T> mObserver;
    boolean mActive; // 标记是否激活了
    // 重点代码,标记最后一次发送数据的版本,默认是-1
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer<? super T> observer) {
        mObserver = observer; // 子类继承后需要调用usper来赋值
    }
    // 抽象方法,由子类LifecycleBoundObserver实现
    abstract boolean shouldBeActive();

    boolean isAttachedTo(LifecycleOwner owner) {
        return false;// 默认是false,子类会重写此方法
    }

    void detachObserver() {
    }
   
    // 重点方法:也是由子类调用,用来更新状态,当子类的生命周期状态监听发生变化就会回调到这里
    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            // 状态相同,忽略
            return;
        }
        // immediately set active state, so we'd never dispatch anything to inactive
        // owner
        mActive = newActive; // 更新状态
        boolean wasInactive = LiveData.this.mActiveCount == 0;
        LiveData.this.mActiveCount += mActive ? 1 : -1;
        if (wasInactive && mActive) {
            // 回调给LiveData,当前是激活状态
            onActive();
        }
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            // 回调给LiveData,当前是非激活状态
            onInactive();
        }
        if (mActive) {
            // 如果激活了,调用下面方法进行分发,后面会重点介绍,这个方法是LiveData的方法
            dispatchingValue(this);
        }
    }
}

2.4 LifecycleEventObserver接口分析

来看看LifecycleEventObserver接口,很简单,只是继承了LifecycleObserver,并且提供了一个方法用来通知状态变更

public interface LifecycleEventObserver extends LifecycleObserver {
    /**
     * Called when a state transition event happens.
     *
     * @param source The source of the event
     * @param event The event
     */
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

分析到这里,我们可以清楚的知道,当我们调用LiveData的observer的时候其实是调用了owner的getLifecycle().addObserver添加了一个经过包装后的LifecycleBoundObserver观察者

三、数据发送源码分析

3.1 LiveData的postValue/setValue方法分析

看完了上面观察者的注册分析后,那么我们的LiveData什么时候会通知观察者呢?不用想,肯定是数据更新的时候,而数据的更新是我们代码自己控制的,如请求网络返回User信息后,我们会主动将User放入MutableLiveData中,这个时候就要用到postValue或者setValue方法了,由于LiveData是一个抽象类且这2个方法都是protected的,而它的子类MutableLiveData中是重写了这2个方法的.

public class MutableLiveData<T> extends LiveData<T> {
    // 带参数构造方法
    public MutableLiveData(T value) {
        super(value);
    }
    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value); // 调用super方法
    }

    @Override
    public void setValue(T value) {
        super.setValue(value); // 调用super方法
    }
}

来看看父类做了啥

static final int START_VERSION = -1;
private volatile Object mData; // 维护的数据
private int mVersion = START_VERSION; // 维护的版本,每次发送数据都会自增

// 运行在子线程
protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    /// 发送到主线程中
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        // 最终还是调用下面的setValue方法发送数据
        setValue((T) newValue);
    }
};

// 运行在主线程
@MainThread
protected void setValue(T value) {
    assertMainThread("setValue"); // 判断是否在主线程
    mVersion++; // 重点代码,版本自增
    mData = value; // 保存数据
    // 重点方法
    dispatchingValue(null);
}

3.2 LiveData的dispatchingValue方法分析

可以看到调用 dispatchingValue()方法并传入null,表示将数据分发给各个观察者, 下面来分析此方法的具体逻辑

private boolean mDispatchingValue; // 标记当前是否正在分发数据

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    // 更新标记
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            // 标注1:如果传入的不是null,那么调用下面的方法通知观察者
            // 还记得上面分析ObserverWrapper源码的activeStateChanged方法吗
            // 没错当LifecycleBoundObserver监听到owner状态变化后会调用其父类ObserverWrapper的activeStateChanged方法,
            // 然后activeStateChanged方法会在mActive=true的时候调用considerNotify方法
            considerNotify(initiator);
            initiator = null;
        } else {
            // initiator=null进来
            // 否则遍历所有的观察者,还记得这里的map吗,他就是mObservers,key=observer,value=LifecycleBoundObserver
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                //标注2: 通知所有的LifecycleBoundObserver
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

3.3 LiveData的considerNotify方法分析

从标注1可以看出,dispatchingValue()参数传null和不传null的区别就是如果传null将会通知所有的观察者,反之仅仅通知传入的观察者。我们直接看标注2,通知所有的观察者通过遍历 mObservers ,将所有的 ObserverWrapper 拿到,实际上就是我们上面提到的 LifecycleBoundObserver,通知观察者调用considerNotify()方法,这个方法就是通知的具体实现了。

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        // 如果LifecycleBoundObserver维护的状态,切切来说是它的父类ObserverWrapper的mActive=false,那么忽略数据的发送
        return;
    }
    // 这里通过observer.shouldBeActive间接的判断owner的状态,这里主动调用一次也是为了保证状态更加精确
    // 因为上面的observer.mActive判断是被动监听的
    if (!observer.shouldBeActive()) { 
        // 如果owner的状态不可见,那么通知状态变化,更新的observer.mActive的值=false
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        // 重点方法,对比LifecycleBoundObserver的mLastVersion版本和LiveData的版本mVersion,如果相同或者大于LiveData的,则忽略数据的发送
        return;
    }
    // 上面经过重重筛选后来到这里,说明是需要发送数据,更新mLastVersio的版本
    // 而mVersion的值在上面分析postValue方法的时候我们知道每次调用的时候都会自增
    observer.mLastVersion = mVersion;
    // 通知真正的观察者,也就是我门注入的观察者,它维护在LifecycleBoundObserver中
    observer.mObserver.onChanged((T) mData);
}

如果观察者不是活跃状态,将不会通知此观察者,看最后一行,observer.mObserver.onChanged((T) mData),observer.mObserver就是我们调用LiveData的observer()方法传入的 Observer,然后调用 Observer 的 onChanged((T) mData)方法,将保存的数据mData传入,也就实现了更新。在看下我们实现的Observer:

viewModel.getUser().observe(MainActivity.this, new Observer<User>() {
    @Override
    public void onChanged(@Nullable User user) {
        if (user != null) {
            tvUser.setText(user.toString());
        }
    }
});

如果哪个控件要根据user的变更而及时更新,就在onChanged()方法里处理就可以了。到这里,LiveData已经能够分析完了,其实LiveData的实现还是要依赖于Lifecycle。

四、LiveData的粘性事件

4.1 何为粘性事件

即发射的事件如果早于注册,那么注册之后依然可以接收到的事件称为粘性事件。

4.2 发生粘性事件的原因

粘性事件通常会出现在多个页面共用同一个单例的LiveData对象的场景,究其原因就是因为LiveData的mVersion大于LifecycleBoundObserver的mLastVersion导致的。因为LiveData的mVersion是用来标记发送数据的次数的,每调用一次postValue或者setValue方法就会让mVersion自增一次,而前面分析源码的时候我门知道当mVersion > mLastVersion的时候就会将数据发送给我们设置的观察者的onChanged方法。

至于为什么初次设置监听会出现mVersion > mLastVersion的情况呢?
首先我需要说明下,mVersion和mLastVersion的默认值都是等于START_VERSION常量,它的值就是-1, 因此我们第一次使用LiveData肯定是mVersion=mLastVersion=-1的,因此首次设置observer进行监听的时候是不会出现粘性事件。

但是,如果现在有2个Activity页面分别是A页面和B页面,A和B页面都是同时使用一个单例的LiveData对象,下面开始分析:

  • A页面设置监听,同时发送一次数据,那么LiveData的mVersion+1后变成0, 同时A页面设置observer会收到通知,因为LifecycleBoundObserver第一次添加到Lifecycler的时候,它的mLastVersion=-1,因此满足mVersion>mLastVersion, 所有A页面能收到通知,而此时B页面还没有打开,所以并没有触发添加监听的操作,因此B收不到通知。

  • A页面跳到B页面,B页面在onCreate使用同一个LiveData进行事件的observer监听,它会立刻收到粘性事件,因为此时的LiveData的mVersion变成了0, 而B页面Lifecycler在注册observer的时候也是一个新的LifecycleBoundObserver, 即mLastVersion是-1,因此满足mVersion>mLastVersion,所以B页面收到粘性事件。

4.3 从源码角度分析粘性事件

由于粘性事件是在设置observer的时候发生,因此我们还是从LiveData的observer方法入手分析

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        // 上面我们都分析过了,这里就不分析了,重点来分析下面这行代码
        owner.getLifecycle().addObserver(wrapper);
    }

此处getLifeCycle获取的对象是LifecycleRegistry对象,查看AppcompatActivity的getLifecycle方法就可以知道原因了,它最终会调用ComponentActivity的getLifecycle方法

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner {
    ...
    // 这里可知mLifecycleRegistry就是LifecycleRegistry对象
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
   public Lifecycle getLifecycle() {
       // 返回一个mLifecycleRegistry对象
       return mLifecycleRegistry;
   }
}

因此,我们需要来分析LifecycleRegistry的addObserver方法

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    // 判断状态
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 这里将LifecycleBoundObserver又进行了一次包装
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 然后保存到map中
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        // 同样的道理,如果缓存存在,直接返回
        return;
    }
    // 从WeakReference中获取LifecycleOwner
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return; // 获取不到返回
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        // 关键代码
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}

分析上面的关键代码,也就是ObserverWithState的dispatchEvent方法

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        // 关键代码,回调LifecycleBoundObserver的onStateChanged方法
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

当LifecycleBoundObserver的onStateChanged方法触发后就会触发父类的ObserverWrapper的activeStateChanged方法,activeStateChanged又会触发dispatchingValue方法,而最终会触发considerNotify方法,这个过程熟悉吧,我们上面分析LiveData原理的时候也分析到了,而且重点分析了dispatchingValue方法,当他传入null的时候会分发所有的观察者,当传入具体的ObserverWrapper时就会只会单独回调该ObserverWrapper,这里分析首次注册观察者的时候刚好对应的就是这种情况。

由上面分析得知,但我们首次调用LiveData的observer方法进行观察者注册的时候,其实是会触发LiveData的considerNotify方法触发的,这也就为粘性事件的分发提供了先天条件, 而必要条件就是mVersion > mLastVersion.

4.4 如何避免粘性事件

既然已经知道了原因,那么怎么解决呢? 我这里介绍2种方案:
1、因为每个LiveData都维护了一个mVersion,为了避免影响,我们在注册观察者的时候使用不同的LiveData对象就可以避免相互影响了.
2、自己维护LiveData和mVersion和ObserverWrapper的mLastVersion,这就需要我们重写LiveData了.

这里介绍方式2, 代码如下:

public class BaseLiveData<T> extends MutableLiveData<T> {

    private int mVersion = -1; // 维护自己的mVersion
    private boolean isSticky; // 控制是否允许粘性事件存在

    public BaseLiveData(boolean isSticky) {
        this.isSticky = isSticky;
    }

    public BaseLiveData() {
        this(false); // 默认构造方法不支持粘性事件
    }

    // 重写数据监听的方法
    @Override
    public void observe(LifecycleOwner owner, Observer<? super T> observer) {
        if (isSticky) {
            // 默认的注册方式就是支持粘性事件的
            super.observe(owner, observer);
        } else {
            // 走下面的方式就是屏蔽粘性事件的
            super.observe(owner, new WrapperObserver<T>(observer, BaseLiveData.this));
        }
    }

    // 重写属性发送的方法
    @Override
    public void setValue(T value) {
        super.setValue(value);
        mVersion++;
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
        mVersion++;
    }

    static class WrapperObserver<T> implements Observer<T> {

        private int mLastVersion;
        private BaseLiveData<T> mLiveData;
        private Observer<? super T> mObserver; // 外部注册的观察者

        public WrapperObserver(Observer<? super T> observer, BaseLiveData<T> liveData) {
            mObserver = observer;
            mLiveData = liveData;
            // 这是关键,当WrapperObserver首次注册的时候让mLastVersion=mVersion,这样首次注册的时候就不会触发mObserver的onChanged了
            mLastVersion = mLiveData.mVersion;
        }

        @Override
        public void onChanged(T t) {
            // 下面的操作其实是参考LiveData的considerNotify原理
            if (mLastVersion >= mLiveData.mVersion) {
                return;
            }
            // 更新mLastVersion
            mLastVersion = mLiveData.mVersion;
            // 回调出去
            mObserver.onChanged(t);
        }
    }
}

下面写一个Demo来验证下,MainActivity布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_info"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:gravity="center"
        android:textColor="#ff0000"
        android:textSize="22sp" />

    <Button
        android:onClick="sendEvent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送事件" />

    <Button
        android:onClick="showFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="加载Fragment" />

    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
LinearLayout>

很简单,2个Button分别用来发送事件和加载Fragment, 然后TextView用来显示接收到的事件,FrameLayout用来显示Fragment.

来看看MainActivity代码:

public class MainActivity extends AppCompatActivity {
    // 这里传入true,表示支持粘性事件
    private static BaseLiveData<String> mLiveData = new BaseLiveData<>(true);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 监听事件
        mLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String data) {
                TextView textView = findViewById(R.id.tv_info);
                textView.setText(data);
            }
        });
    }
    // 发送事件
    public void sendEvent(View view) {
        mLiveData.postValue("hello world");
    }
    
    // 添加fragment
    public void showFragment(View view) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fl_content, new MyFragment()).commit();
    }

   public static class MyFragment extends Fragment {
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            TextView textView = new TextView(getActivity());
            textView.setTextSize(22f);
            textView.setGravity(Gravity.CENTER);
            textView.setTextColor(Color.BLUE);
            textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200));
            return textView;
        }

        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            // 使用和MainActivity同一个LiveData来监听事件
            mLiveData.observe(this, new Observer<String>() {
                @Override
                public void onChanged(String data) {
                    TextView textView = (TextView) view;
                    textView.setText(data);
                }
            });
        }
    }
}

我们先来看看支持粘性事件的效果,也就是BaseLiveData构造方法传入true的情况:
LiveData的工作原理分析_第1张图片
可以看到点击发送数据的时候MainActivity显示了数据, 然后点击添加MyFragment,由于此时是支持粘性事件的,MyFragment的onViewCreated调用 mLiveData.observe的事件立马就收到了粘性事件,然后显示了数据.

现在我们来将BaseLiveData构造方法的参数去掉,使用无参数的构造方法,也就是不支持粘性事件的情况,看看效果图:
LiveData的工作原理分析_第2张图片
由此可见,我们的BaseLiveData是支持屏蔽粘性事件的.

你可能感兴趣的:(源码分析)