美文网首页Android开发
LiveData 真香,你确定不来试试?

LiveData 真香,你确定不来试试?

作者: 毛先森 | 来源:发表于2020-06-02 10:46 被阅读0次

前言

前段时间忙着新项目的直播功能,终于在提测以后有点时间来看看源码了。直播项目在确定方案以后,根据 sdk 提供的文档和 demo ,花了两天时间对直播 sdk 进行二次封装,将通用逻辑分层,以后的项目就可以实现快速接入。通过直播sdk的接入踩坑,也算是对音视频开发有了些了解,自己的技术方向就定位在音视频、ndk,之后也会出篇直播相关的技术博客。

首先在看 LiveData 源码以前,先提出几个疑问

  1. LiveData 怎样根据生命周期来通知观察者
  2. LiveData 怎样存储数据
  3. 为什么主线程调用 setVaule(),子线程使用 postVaule()

相关链接

Google Git LiveDataCore

从源码的角度深入理解SafeIterableMap

LiveData 类

LiveData 是一个抽象类,其中定义了数据传递的主要逻辑,可以看出遵守开闭原则。在成员变量中有一个 object 对象,用于 postVaule 时锁住 LiveData 对象,防止多线程问题。

内部定义一个 ObserverWrapper 抽象类,处理与 Lifecycle 对应的状态,而 LifecycleBoundObserver 内部类则实现了 ObserverWrapper

LifecycleBoundObserver

内部持有了 LifeCyclerOwner,可获取到当前生命周期的状态,当 Activity、Fragment 销毁时,移除观察者,从而避免内存泄漏。

     @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
                
            // 如果已经回调 onDestroy(),则移除观察者    
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

postValue -子线程使用

子线程传递数据到主线程,首先判断上一次待传递的值 (mPendingData)是否已经发布出去,如果上一次的还未发布则 return,否则使用线程管理器将一个子线程调度到主线程执行

   protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

setValue -主线程使用

在设置值之前,判断当前是否为主线程,否则抛出异常

    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        // 此处设置 null,是为了使用迭代器遍历通知所有处于活跃状态的观察者
        dispatchingValue(null);
    }
    
    
    /**
    *  1.入参为 null 时,遍历通知
    *  2.入参不为空,则指定通知该观察者
    */
     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;
    }
    
    

总结

对于开头提出的问题,在查看源码过后,自己心里已经有了答案

  • LiveData 怎样根据生命周期来通知观察者

    LiveData 是 LifeCycler 的分支,也就是说 LiveData 在观察者活跃时通知的特性,是基于 LifeCycler 实现的,因为内部持有了 LifeCyclerOwner,可以通过 LifeCyclerOwner.getLifeCycler() 获取生命周期的状态

  • LiveData 怎样存储数据

    LiveData 内部保存了所有观察者的集合,使用 SafeIterableMap 来保存,非线程安全型的,支持在遍历环节修改,SafeIterableMap 内部使用了 WeakHashMap,防止内存泄漏

  • 为什么主线程调用 setVaule(),子线程使用 postVaule()

    因为最终都会在主线程发布通知,而这两个方法且别在对当前线程的调度,setVaule ()方法会判断当前是否为主线程, postVaule()会将 Runnable 调度到主线程

相关文章

  • LiveData 真香,你确定不来试试?

    前言 前段时间忙着新项目的直播功能,终于在提测以后有点时间来看看源码了。直播项目在确定方案以后,根据 sdk 提供...

  • 你确定你不来?

  • LiveData 源码分析

    前言 最近的项目重构中加入LiveData框架,并且小码的T-MVVM也是用了LiveData框架,好不好用你试试...

  • 关于吃饭

    这菜好油 你吃的真多 下次还带我来吗 为啥不来呢 这菜真的好油 下次不来了 不来你试试 油真多 嗯嗯 嘴上的

  • LiveData实现原理

    LiveData使用LiveData LiveData = new LiveData(); liveData.ob...

  • 十字绣玩腻了?试试这个吧!

    简单实用又好看的针插,你确定不试试吗?

  • 确定不来吗?

    看见水就发狂的人,小心了,来此处游玩,我不会丢救生圈给你的/奸笑 西风送凉,岁月静好。 只盼君来,共赏此景。 ...

  • Android知识点进阶-探究LiveData

    发现问题 初识livedata,想在项目中用着试试,于是尝试了个demo: 先定义retrofit接口ApiLib...

  • 星辰随笔‖不就是折腾嘛,试试

    星辰随笔《不就是折腾嘛,试试》 原创/似此星辰同昨日 时间走得很快,等不来的日子谁也没辙,确定自己的准备已经做好了...

  • 6.26.我在烧钱的地方思考人生

    你说金钱不是万能的,我就呵呵呵。 你说金钱买不到时间,你试试迪士尼快速通道。 你说金钱买不来快乐,你试试迪士尼快速...

网友评论

    本文标题:LiveData 真香,你确定不来试试?

    本文链接:https://www.haomeiwen.com/subject/czoyzhtx.html