写点什么

Android 开发把 -LiveData- 用于事件传递那些坑,一文详解

用户头像
Android架构
关注
发布于: 4 小时前

postSetValue(mld, d);}}


/**


  • 向主线程的 handler 抛 SetValueRunnable*/public static <T> void postSetValue(MutableLiveData<T> mld, T d) {if (sMainHandler == null) {sMainHandler = new Handler(Looper.getMainLooper());}sMainHandler.post(SetValueRunnable.create(mld, d));}


private static class SetValueRunnable<T> implements Runnable {private final MutableLiveData<T> liveData;private final T data;


private SetValueRunnable(@NonNull MutableLiveData<T> liveData, T data) {this.liveData = liveData;this.data = data;}


@Overridepublic void run() {liveData.setValue(data);}


public static <T> SetValueRunnable<T> create(@NonNull MutableLiveData<T> liveData, T data) {return new SetValueRunnable<>(liveData, data);}}}

3.2、非激活状态的问题

其实我觉得这个问题的主要「责任」并不在 LiveData,而是在它的观察者,「是你告诉我你非激活的呀,那我怎么给你发数据呢,我发给你,万一你出问题了呢,那到底谁负责?」。我们常用的观察者其实是 LifecycleBoundObserver,在调用 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) 会自动帮我们封装一个这样的观察者,而它会根据 LifecycleOwner 的生命周期呈现出「激活」和「非激活」状态。


// LifecycleBoundObserverboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}


LiveData 默认的还有另外一种观察者 AlwaysActiveObserver,它是我们在调用 public void observeForever(@NonNull Observer<? super T> observer) 时生成的,顾名思义它会一直处于激活状态,LiveData 当然也不会替我们管理这样观察者的生命周期,我们需要在不使用时手动调用 public void removeObserver(@NonNull final Observer<? super T> observer) 移除观察者,否则可能会内存泄漏。


// AlwaysActiveObserverboolean shouldBeActive() {return true;}


这个 AlwaysActiveObserver 看样子能够解决我们的问题,他一直处于激活状态,那所有的事件都会回调给他,但是需要我们自己管理生命周期。这不是开历史倒车吗?好不容易有生命周期感知了,现在又要自己手动搞?

3.3、造一个生命周期感知的还不丢事件的观察者

手动管理生命周期是绝对不能忍的,AlwaysActiveObserver 可以解决刚才说的问题,那我们就造一个新的观察者来管理 observeForever 和 removeObserver 的问题。既然要造,那就造个好用的,首先事件一定不能丢,要不就没意义了;而且生命周期要观察者自己管理,不能只是简单的 observeForever 和 removeObserver,非激活状态之类的也要考虑进去。既然要管理生命周期,那就不得不用到 LifecycleOwner、Lifecycle,然后自己观察 LifecycleOwner 的 Lifecycle。


/**


  • Marks a class as a LifecycleObserver. It does not have any methods, instead, relies on

  • {@link OnLifecycleEvent} annotated methods.

  • <p>

  • @see Lifecycle Lifecycle - for samples and usage patterns.*/@SuppressWarnings("WeakerAccess")public interface LifecycleObserver {


}


Lifecycle 对外只给了这个接口,并不含有任何回调,我们需要用注释里说的 OnLifecycleEvent 注解来标记相应的函数,Lifecycle 会通过反射拿到标记的函数,然后生成对应的适配器,感兴趣的可以看下 Lifecycling.getCallback 函数。比如我们可以这样用


public class Observer implements LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_START)private void onStart() {doSomethingOnStart();}}


拿到生命周期后,我们就可以在一开始 observeForever,在 Lifecycle.Event.ON_DESTROYremoveObserver。接下来就要考虑激活和非激活的状态了,既然用了 observeForever,那每次事件都会有回调,这时候如果 Lifecycle 处于激活状态,那可以直接把事件发出去。但如果非激活,不能直接把事件发出去,又不能丢,那我们就需要先把事件存起来,然后在 Lifecycle 变为激活状态时再把存起来的事件发送出去。简单画了下流程图。



/**


  • LiveData 用作事件传递时的观察者

  • 保证所有事件不丢失,保存非激活状态的事件,并能够在激活状态回调,且没有内存泄漏

  • @see AsEventBus

  • @author funnywolf

  • @since 2019-05-18*/public class LiveEventObserver<T> implements LifecycleObserver, Observer<T


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


{private LiveData<T> mLiveData;private LifecycleOwner mOwner;private Observer<? super T> mObserver;


private final List<T> mPendingData = new ArrayList<>();


public LiveEventObserver(LiveData<T> liveData, LifecycleOwner owner, Observer<? super T> observer) {mLiveData = liveData;mOwner = owner;mObserver = observer;mOwner.getLifecycle().addObserver(this);mLiveData.observeForever(this);}


/**


  • 在生命周期结束前的任何时候都可能会调用*/@Overridepublic void onChanged(@Nullable T t) {if (isActive()) {// 如果是激活状态,就直接更新 mObserver.onChanged(t);} else {// 非激活状态先把数据存起来 mPendingData.add(t);}}


/**


  • @return 是否是激活状态,即 onStart 之后到 onPause 之前*/private boolean isActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);}


/**


  • onStart 之后就是激活状态了,如果之前存的有数据,就发送出去*/@OnLifecycleEvent(Lifecycle.Event.ON_ANY)private void onEvent(LifecycleOwner owner, Lifecycle.Event event) {if (owner != mOwner) {return;}if (event == Lifecycle.Event.ON_START || event == Lifecycle.Event.ON_RESUME) {for (int i = 0; i < mPendingData.size(); i++) {mObserver.onChanged(mPendingData.get(i));}mPendingData.clear();}}


/**


  • onDestroy 时解除各方的观察和绑定,并清空数据*/@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)private void onDestroy() {mLiveData.removeObserver(this);mLiveData = null;


mOwner.getLifecycle().removeObserver(this);mOwner = null;


mPendingData.clear();


mObserver = null;}


public static <T> void bind(@NonNull LiveData<T> liveData,@NonNull LifecycleOwner owner,@NonNull Observer<? super T> observer) {if (owner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {return;}new LiveEventObserver<>(liveData, owner, observer);}}

3.4、保证 LiveData 的事件更新

3.1 也说过要自己处理 postValue,其次要保证用我们自己定义的观察者,需要重写 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)。


/**


  • 用作事件总线的 {@link MutableLiveData}

  • @see AsEventBus

  • @author funnywolf

  • @since 2019-05-18*/public class EventMutableLiveData<T> extends MutableLiveData<T> {@Overridepublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {LiveEventObserver.bind(this, owner, observer);}


@Overridepublic void postValue(T value) {LiveDataUtils.setValue(this, value);}}


/**


  • 用作事件总线的 {@link MediatorLiveData}

  • @see AsEventBus

  • @author funnywolf

  • @since 2019-05-18*/public class EventMediatorLiveData<T> extends MediatorLiveData<T> {

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android开发把-LiveData-用于事件传递那些坑,一文详解