AAC学习笔记LiveData(二)

本文为《Android Architecture Components学习笔记》的一部分
水平有限,如有不当之处请不吝赐教

上一篇模拟了简单的LiveData,以及MediatorLiveData部分内容。本篇就是对几个成员做个完整的探究。


LiveData:

ObserverWrapper

    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive; //是否活动
        int mLastVersion = START_VERSION; //初始化mLastVersion为-1

        ObserverWrapper(Observer<? super T> observer) {mObserver = observer;}

        abstract boolean shouldBeActive();  //你说老子是不是活的
         //所有者?我的所有者!
        boolean isAttachedTo(LifecycleOwner owner) {return false;} 

        void detachObserver() {} //分开了,拜拜

        void activeStateChanged(boolean newActive) {   //主动的刷新
            if (newActive == mActive) {return;}
            // 设置活动状态,保证仅向活动状态所有者发送
            mActive = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            //如果没有观察者,并且设置第一个观察者状态为活动,执行onActive()
            if (wasInactive && mActive) { onActive(); }  
            //最后一个观察者离开的时候,真的就得凉凉
            if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); }
            //进入活动状态,就通过dispatchingValue(这个方法后面会详细说明)安排~~
            if (mActive) {dispatchingValue(this);}
        }
    }

这是观察者的包装类,里面加的东西我上面都写出啦。

observeForever()

先看内部类:AlwaysActiveObserver,这货可以观察到死。

    private class AlwaysActiveObserver extends ObserverWrapper {
        AlwaysActiveObserver(Observer<? super T> observer) {super(observer);}
        boolean shouldBeActive() {return true;} } //永远都在喊,我是活得

observeForever()添加了AlwaysActiveObserver

    //将给定的观察者添加到观察者列表中。但它始终是active的,并不会被自动删除
    //可以调用removeObserver(Observer)来停止
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
       //如果存在就抛异常、退出
        if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {... }
        if (existing != null) { return;}        
        wrapper.activeStateChanged(true);
    }

为什么要有个活动状态呢,后面可以看到通过observe添加的观察者是生命周期相关的,需要改变活动状态。而通过改变状态又可以实现一次从无到有的“调度”所以会有这样的设计。

observe()

observeForever()不同,observe添加的是LifecycleBoundObserver

    class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) { super(observer);  mOwner = owner; }

        //老子可以睡觉的。这回是不是活的,得看看了
        boolean shouldBeActive() { 
        		return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); }

        //既然能睡就可以醒来,醒来也可以睡去~~
        //这个变化是通过这个方法处理的
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
             //皮之不在毛将焉附
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {    
                removeObserver(mObserver); return; }   //删了走人
            activeStateChanged(shouldBeActive());      //积极的刷刷,刷前别忘了看状态
        }
        //看看是谁,所有者是不是一个
        boolean isAttachedTo(LifecycleOwner owner) {return mOwner == owner;}
        //彻底分手,拜拜。把我Observer丢掉吧
        void detachObserver() {mOwner.getLifecycle().removeObserver(this); }
    }
  • 这是与生命周期相关的观察者,所以要存在owner,持有者的状态决定了观察者的状态。
  • LiveData会管理这些与生命周期相关的数据。
  • 同时,这个类的对象就不是可以永远活动的对象。

举个例子:如果持有者是Fragment,如果这个Fragment销毁了自然它的观察者们也就需要删除掉。

LifecycleBoundObserver需要通过observe添加的:

    //将观察者添加到给定所有者的生命周期内的观察者列表中。
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //所有者是DESTROYED话,扭头就走
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {  return;  }
        
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //如果所有者已经存在,则退出。
        if (existing != null && !existing.isAttachedTo(owner)) {...}//抛异常
        if (existing != null) {  return;    }
        //我得放个哨兵在你的里面
        owner.getLifecycle().addObserver(wrapper);
    }

主要方法

前面的observeForever()observe()都是用来增加观察者的。
我们可以从头继续往下走了~~

public abstract class LiveData<T> {

    final Object mDataLock = new Object();
    static final int START_VERSION = -1;
    static final Object NOT_SET = new Object();

	//存放观察者。SafeIterableMap是链表而非Map,支持在迭代过程中修改,非线程安全
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();

    // 有多少观察者处于活动状态
    int mActiveCount = 0;
    //保存自己的数据
    private volatile Object mData = NOT_SET;
    //volatile关键字保证当数据改变后其他线程立即可见
    //当调用setData时,先设置为挂起数据mPendingData,并在主线程上进行数据交换
    volatile Object mPendingData = NOT_SET;
    private int mVersion = START_VERSION;

    private boolean mDispatchingValue;      
    private boolean mDispatchInvalidated;   

    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() { Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }  setValue((T) newValue);}};

    //通知变更,也就是执行观察者的onChanged()方法
    private void considerNotify(ObserverWrapper observer) {
        //先检查观察者。保证为活动的事件入口。
        if (!observer.mActive) {return;}        
        //即使观察者成为活动状态,如果我们没有收到那个事件,就退出     
        if (!observer.shouldBeActive()) {observer.activeStateChanged(false);  return;}        
        //检查调度的最新状态。有可能更新了但还没收到。
        if (observer.mLastVersion >= mVersion) {return;}
        
        observer.mLastVersion = mVersion; 
        observer.mObserver.onChanged((T) mData);
    }

    //调度值变更,当LiveData数据发生改变时,通过此方法遍历观察者以执行其onChanged()方法
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //如果调度过程进行中,则mDispatchInvalidated调度无效
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {  //如果有明确的发起者(Observer),就执行一下
                considerNotify(initiator);
                initiator = null;
            } else {                 //如果发起者为空,就通过迭代器遍历所有观察者
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {break;}//如果被干扰,就立即跳出
                }}
        } while (mDispatchInvalidated); //如果被干扰,那么从头来一遍
        mDispatchingValue = false;
    }
    @MainThread  //移除某个观察者
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        //如果删除成功就会返回删除的那个Observer
        ObserverWrapper removed = mObservers.remove(observer); 
        if (removed == null) { return;  }
        
        removed.detachObserver();
        removed.activeStateChanged(false);
    }
    @MainThread  //逐个全部移除
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            if (entry.getValue().isAttachedTo(owner)) { removeObserver(entry.getKey());  } } }

    //向主线程发更新数据
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

    //在主线程更新数据
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

    //返回值,但后台线程上可能返回不了最新值
    @Nullable
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            //noinspection unchecked
            return (T) data;
        }
        return null;
    }

    int getVersion() {  return mVersion;  }
    //当活动观察者的数量从0变为1时触发
    protected void onActive() { }

    //当活动观察者的数量从1变为0时触发,但可能还存在观察者(状态不是STARTED、RESUMED)
    //可以通过hasObservers()查看是否还有观察者
    protected void onInactive() {  }
    public boolean hasObservers() {  return mObservers.size() > 0;  }
    public boolean hasActiveObservers() {return mActiveCount > 0; }//是否还有活动的观察者

    private static void assertMainThread(String methodName) {if (!ArchTaskExecutor.getInstance().isMainThread()) {...}}//抛异常    
}

这便是整个LiveData了,通过一个链表保存一串观察者,当数据发生变化的时候通知他们更新。观察者分为与生命周期持有者相关的以及永远活动状态的。

MediatorLiveData

MediatorLiveData是 LiveData的子类,它可以观察到其他LiveData对象,并对OnChanged事件作出反应。
该类可以正确地将其活动/非活动状态反馈到被观察的LiveData对象。

先上一个简单的例子

先看看在文档里的一个列子:
有两个LiveData实例,命名为liveData1和liveData2
将它们合并到liveDataMerger中。让liveData1和liveData2都成为MediatorLiveData liveDataMerger的源
调用任何一个onChanged时,都会在liveDataMerger中设置一个新值。

LiveData<Integer> liveData1 = ...;
LiveData<Integer> liveData2 = ...;

MediatorLiveData<Integer> liveDataMerger = new MediatorLiveData<>();
liveDataMerger.addSource(liveData1, value -> liveDataMerger.setValue(value));
liveDataMerger.addSource(liveData2, value -> liveDataMerger.setValue(value));

如果我们想将liveData1发出的10个值合并到liveDataMerger中
在10个值之后,我们停止监听liveData1并将其删除

liveDataMerger.addSource(liveData1, new Observer<Integer>() {
    private int count = 1;
    @Override 
    public void onChanged(Integer s) {
        count++;
        liveDataMerger.setValue(s);
        if (count > 10) { liveDataMerger.removeSource(liveData1); }}});

内部类source

    private static class Source<V> implements Observer<V> {
        final LiveData<V> mLiveData;            //被观察的数据
        final Observer<? super V> mObserver;    //观察者
        int mVersion = START_VERSION;

        Source(LiveData<V> liveData, final Observer<? super V> observer) {
            mLiveData = liveData; mObserver = observer;}

        //在被观察者上增加观察者,注意这里使用了observeForever()。也就是这个加入后活到死
        void plug() {mLiveData.observeForever(this);}     
        //在被观察者上,删除观察者
        void unplug() {mLiveData.removeObserver(this);}   
        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();        //更新版本
                mObserver.onChanged(v);                   //刷新一下保持数据同步
            }}}

这个Source指定了观察者与被观察者,并且可以将观察者在被观察者上执行加入或分离操作。

几个很常规的方法

public class MediatorLiveData<T> extends MutableLiveData<T> {
    //存放被观察者(数据源)的容器,关于SafeIterableMap我有一个很详细的说明大家可以关注一下
    private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();
    // 开始监听被观察者, onChanged会在source值发生变化时被调用。
    //onChanged回调只在MediatorLiveData活动时调用。
    public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
        Source<S> e = new Source<>(source, onChanged);
        Source<?> existing = mSources.putIfAbsent(source, e);
        //如果给定的LiveData已经作为一个源添加,但是使用不同的观察者,抛异常,并返回
        if (existing != null && existing.mObserver != onChanged) {...}
        if (existing != null) {return;}
        if (hasActiveObservers()) {e.plug();}   //有活动的观察者,就可以加入
    }

    //停止监听被观察者
    @MainThread
    public <S> void removeSource(@NonNull LiveData<S> toRemote) {
        Source<?> source = mSources.remove(toRemote); 
        //如果返回自己,则意味着删除成功,执行分离观察者的操作
        if (source != null) {source.unplug();}}         

    @Override
    protected void onActive() {
        //遍历所有被观察者并激活他们(执行plug操作)
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().plug();}}

    @Override
    protected void onInactive() {
        //遍历所有被观察者并分离他们(执行unplug操作)
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().unplug(); }}
}

MutableLiveData

这个类主要是开放了两个LiveData里protected方法

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);}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值