LiveData从使用到源码

介绍

LiveData 是一个可以在给定生命周期内观察到的数据持有者类。这意味着观察者可以与 LifecycleOwner 成对添加,并且只有当配对的 LifecycleOwner 处于活动状态时,才会通知该观察者包装数据的修改。如果 LifecycleOwner 的状态为 Lifecycle.State.STARTED 或 Lifecycle.State.RESUMED,则认为 LifecycleOwner 处于活动状态。通过 observeForever(Observer) 添加的观察者被视为始终处于活动状态,因此将始终收到有关修改的通知。

使用

        MutableLiveData<Object> liveData = new MutableLiveData<>();
        liveData.setValue("hello LiveData");
        liveData.observe(this, new Observer<Object>() {
            @Override
            public void onChanged(Object o) {
                Log.e(TAG, "onChanged: o: " + o);
            }
        });
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                liveData.setValue(new Date().toString());
            }
        });

先上log

 这是直接运行没有点击按钮打印的日志,可以看到LiveData是支持接收粘性事件的下面我们就从源码上看LiveData是如何做到粘性事件的发送因为接收方是observe我们就从注册观察者开始看起

LiveData#obsever


    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //校验activity是已经销毁
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

        //注释1
        //尝试将这个观察者保存到数据结构中
        //注意mObservers中内部维护着双向链表
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //这里校验之前这个observer是否已经存储过
        //如果之前存储过且这次绑定的LifecycleOwner又不相同则抛出异常,异常情况可不过多关注
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        //注意保存observer这里,如果是首次保存existing应为nulll
        if (existing != null) {
            return;
        }
        //这里则是添加当前Activity生命周期的观察者
        owner.getLifecycle().addObserver(wrapper);
    }

    //对应注释1
    public V putIfAbsent(@NonNull K key, @NonNull V v) {
        Entry<K, V> entry = get(key);
        if (entry != null) {
            return entry.mValue;
        }
        put(key, v);
        return null;
    }

上面的代码较为简单,我这里的注释也非常详细了接下来我们看LifecycleBoundObserver中生命周期发生改变后是如果处理的

LifecycleBoundObserver#onStateChanged

        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

    在这里我们首先看到了removeObserver,这就是LiveData为什么我们只需要注册观察者而不需要删除观察者的原因,我们看到重点代码activeStateChanged

LifecycleBoundObserver#activeStateChanged


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


        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            //生命周期start之后的状态newActive = true
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                //事件派发
                dispatchingValue(this);
            }
        }


      void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                //对指定观察者派发事件,刚注册进来走这里
                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;
    }


    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        
        //检测生命周期是否活跃状态
        //create状态是就不会发送事件
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //每次setValue时候mVersion都会自增
        //用于判断最新事件有没有发送过
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //这里就是发送到我们的观察者
        observer.mObserver.onChanged((T) mData);
    }

在这里我们就看到了,LiveData对粘性事件的发送。

接下来我们继续看setValue

LiveData#setValue

    protected void setValue(T value) {
        assertMainThread("setValue");
        //mVersion上面我们已经看到了
        mVersion++;
        mData = value;
        //这段代码我们看面也看到了
        dispatchingValue(null);
    }

LiveData#postValue

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            //当前没有正在post的事件postTask则为true
            postTask = mPendingData == NOT_SET;
            //赋值给全局的mPendingData
            mPendingData = value;
        }

        //如果上次post的事件还没有回调则会在这里return
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }


    public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = createAsync(Looper.getMainLooper());
                }
            }
        }
        //通过handler,post事件是个延迟事件
        mMainHandler.post(runnable);
    }


    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                //将postValue的值保存在局部变量准被发送事件
                newValue = mPendingData;
                //回置mPendingData
                //可以开始接收新的postValue
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值