美文网首页Android开发Android技术知识技术人扯技术
android LiveData源码分析--源码阅读100天(2

android LiveData源码分析--源码阅读100天(2

作者: a49f87ef5d4f | 来源:发表于2018-11-21 21:25 被阅读19次

    0.介绍

    LiveData,同属于JetPack构建集合,根据文档描述LiveData是一个可观察的数据持有者类。与常规observable不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如Activity,Fragment或Service。此感知确保LiveData仅更新处于活动生命周期状态的应用程序组件观察者。
    优势(以下摘自google文档,google翻译了一下)
    (1)确保您的UI符合您的数据状态
    LiveData遵循观察者模式。生命周期状态更改时,LiveData会通知Observer对象。您可以合并代码以更新这些Observer对象中的UI。每次应用程序数据更改时,您的观察者都可以在每次更改时更新UI,而不是更新UI。
    (2)没有内存泄漏
    观察者绑定到Lifecycle对象并在其相关生命周期被破坏后自行清理。
    由于停止活动而没有崩溃
    如果观察者的生命周期处于非活动状态(例如,在后端堆栈中的活动的情况下),则它不会接收任何LiveData事件。
    (3)不再需要手动生命周期处理
    UI组件只是观察相关数据,不会停止或恢复观察。 LiveData自动管理所有这些,因为它在观察时意识到相关的生命周期状态变化。
    (4)始终保持最新数据
    如果生命周期变为非活动状态,则会在再次变为活动状态时接收最新数据。例如,后台活动在返回前台后立即收到最新数据。
    (5)适当的配置更改
    如果由于配置更改(例如设备轮换)而重新创建活动或片段,则会立即接收最新的可用数据。
    (6)共享资源
    您可以使用单例模式扩展LiveData对象以包装系统服务,以便可以在应用程序中共享它们。 LiveData对象连接到系统服务一次,然后任何需要该资源的观察者都可以只观看LiveData对象。

    1.使用

    class MainActivity : AppCompatActivity() {
    
        val curName: MutableLiveData<String> by lazy {
    
            MutableLiveData<String>()
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            curName.observe(this, Observer<String> {
                println("value is $it")
            })
            curName.value="old value"
        }
    
    }
    

    使用很简单,当MutableLiveData对象的value发生改变时会出发Observer的onChanged方法,其中MutableLiveData继承自LiveData。

    2.目的

    (1)LiveData如何进行生命周期感知
    (2)如何更新事件
    (3)如何避免内存泄漏

    3.分析

    3.1LiveData如何进行生命周期感知

    先看一下LiveData的observer方法

    @MainThread
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
            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);
        }
    
    

    看最后一行,owner.getLifecycle().addObserver(wrapper);owner就是咱们用的Activity或者Fragment,这就和上一篇文章Lifecycle对应上了
    android Lifecycle源码分析--源码阅读100天(1),这里添加的监听者就是LifecycleBoundObservr,这个类实现了LifecycleObserver,这就是感应的生命周期的方式。

    3.2如何更新事件

    说实话,这个控件就是个观察者模式,事件的Observer就是这个LifecycleBoundObserver,看看这个对象的onStateChanged方法

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

    看一下activieStageChanged方法

    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) {
                    onActive();
                }
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                    onInactive();
                }
                if (mActive) {
                    dispatchingValue(this);
                }
            }
    

    这个方法前面都是用来处理生命周期防止内存泄漏的,真正的用来观察数据进行处理的就是dispatchingValue方法,看一下这个方法

    private 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<T>, ObserverWrapper>> iterator =
                            mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                        considerNotify(iterator.next().getValue());
                        if (mDispatchInvalidated) {
                            break;
                        }
                    }
                }
            } while (mDispatchInvalidated);
            mDispatchingValue = false;
        }
    

    如果ObserverWrapper参数不为null,就调用considerNotify方法,否则就遍历mObservers,调用considerNotify,那就看一下这个方法

    private void considerNotify(ObserverWrapper observer) {
            if (!observer.mActive) {
                return;
            }
            // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
            //
            // we still first check observer.active to keep it as the entrance for events. So even if
            // the observer moved to an active state, if we've not received that event, we better not
            // notify for a more predictable notification order.
            if (!observer.shouldBeActive()) {
                observer.activeStateChanged(false);
                return;
            }
            if (observer.mLastVersion >= mVersion) {
                return;
            }
            observer.mLastVersion = mVersion;
            //noinspection unchecked
            observer.mObserver.onChanged((T) mData);
        }
    

    首先判断ObserverWrapper是否需要被激活,如果需要被激活就调用activeStateChanged方法,否则就调用 我们自定义的Observer的onChanged((T) mData)方法。

    3.3如何避免内存泄漏

    回到onStateChanged的方法里调用的activeStateChanged(shouldBeActive()),看一下shouldBeActive方法

     @Override
            boolean shouldBeActive() {
                return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
            }
            
     public boolean isAtLeast(@NonNull State state) {
                return compareTo(state) >= 0;
            }        
    

    这个方法就是将当前的state和STARTED进行对比,如果是STARTED或者RESUMED状态,那么传入activeStateChanged的参数就是true,否则就是false,再回看activeStateChanged方法

    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) {
                    onActive();
                }
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                    onInactive();
                }
                if (mActive) {
                    dispatchingValue(this);
                }
            }
        }
    

    当状态没有改变时,直接返回,否则根据newActive进行判断是否为activt状态,

              if (wasInactive && mActive) {
                    onActive();
                }
                if (LiveData.this.mActiveCount == 0 && !mActive) {
                    onInactive();
                }
    

    之后根据mActive和activeCount调用onActive和onInactive方法。这就一目了然了,当生命周期调用onStart之后,就处于激活状态,onstop之后就处于非激活状态,这样数据改变时也就不会走到Observer的方法了,从而避免了内存泄漏。

    image

    关注我的公众号

    相关文章

      网友评论

        本文标题:android LiveData源码分析--源码阅读100天(2

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