我是靠谱客的博主 欣慰绿茶,最近开发中收集的这篇文章主要介绍LiveData详解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

先奉上LiveData官方文档地址:

https://developer.android.com/topic/libraries/architecture/livedata

LiveData是什么?

1、LiveData是一种可观察的数据存储器类。通俗点说就是存储数据,同时可以被观察者观察数据的变化。

2、LiveData具有生命周期感知能力(这玩意儿是不是很眼熟,参考上篇Lifecycle),这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。

LiveData原理分析

首先看LiveData类的observe方法,observe和observeForever的区别在于,observeForever无视生命周期,只要数据改变就会回调通知observer。observe方法主要做了下面几件事儿:

  • 绑定的组件生命周期状态为DESTROYED的时候, 则会忽视订阅请求
  • 将 LifecycleOwner 和 Observer 封装成支持生命周期感知的LifecycleBoundObserver类
  • 观察者只能与一个owner绑定,不允许重复注册
  • 利用Lifecycle,把观察者注册到LifecycleBoundObserver里面去,从而监听宿主生命周期状态的变化
    // 添加跟生命周期相关的 observer
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        // 若 LifecycleOwner 被销毁,则忽略该 observer
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            return;
        }

        // 将 LifecycleOwner 和 Observer 封装成支持生命周期感知的LifecycleBoundObserver
        //下面再解析
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        // 避免重复添加相同的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;
        }

        // 实现对 LifecycleOwner 生命周期的感知  这里可以见lifecycle详解
        owner.getLifecycle().addObserver(wrapper);
    }

    // 无视生命周期, 每次数据发生变化时,都会回调通知 Observer
    // 需要手动在不需要时移除 Observer
    @MainThread
    public void observeForever(@NonNull Observer<T> observer) {
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }

添加宿主生命周期的监听后(owner.getLifecycle().addObserver(wrapper))里面的主要逻辑方法到---》ObserverWithState(dispatchEvent)---》LifecycleBoundObserver(onStateChanged)中间是Lifecycle处理逻辑之前花篇幅写过,为了偷懒这里不做过多解释=。=从LifecycleBoundObserver(onStateChanged)开始讲。

//前面Livedata的observe中有用到dLifecycleBoundObserver是LiveData内部类
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver{
    @NonNull
    final LifecycleOwner mOwner;
 
    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);
        mOwner = owner;
    }
 
    @Override
    boolean shouldBeActive() {
        //组件生命周期状态为活跃时只有2种情形,started和resume
        //观察者是否活跃就等价于宿主的状态是否大于等于STARTED;
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
 
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        //当接收到宿主生命周期的DESTROYED 事件时会自动解除跟 owner 的绑定
        //所以我们不用去手动移除观察者
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        //宿主的状态发生了变化时,此时会判断宿主是否处于活跃状态,
        //如果页面不处于活跃状态,即使状态改变,此时也不会被分发,可以避免后台任务抢占资源,当页面        
        //重新处于活跃状态才会分发。
        activeStateChanged(shouldBeActive());
    }
 
    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }
 
    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}
 

下面进入ObserverWrapper (activeStateChanged)

        void activeStateChanged(boolean newActive) {
            //宿主的活跃状态发生改变时才会往下走,否则直接结束该方法
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            //把新观察者状态赋值给mActive
            mActive = newActive;
            //判断此前处于活跃状态的观察者数是否为0
            boolean wasInactive = LiveData.this.mActiveCount == 0;
        //如果该观察者是由不活跃变为活跃时,则先将处于活动状态的观察者个数加1,否则-1
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            
            if (wasInactive && mActive) {
            //此前没有活跃者,且该观察者由不活跃变活跃
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
            //该观察者是由活跃变不活跃 且之后LiveData中不存在活动状态的观察者
                onInactive();
            }
            if (mActive) {
                //该观察者由不活跃变活跃
                dispatchingValue(this);
            }
        }

mActive表示这个观察者是不是活跃状态【组件生命周期状态为活跃时只有2种情形,started和resume,观察者是否活跃就等价于宿主的状态是否大于等于STARTED】

onActive()和onInactive()都是空方法,可以由开发自己继承去做一些操作。该观察者由不活跃变活跃,进入dispatchingValue(this);

//该方法在两个地方有调用。
//1、在宿主生命周期发生变化的时候。回调LifecycleBoundObserver的onStateChanged方法。最后会调到这个方法,传入this(LifecycleBoundObserver);也就是上边分析的流程
//2、在setValue的时候调用。传入null;
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    // 当前正在处于分发数据中   直接return,继续之前的分发
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        //进该方法体就是有效分发了
        mDispatchInvalidated = false;
        //宿主生命周期状态变化initiator != null; setValue时initiator = null;
        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;
}

dispatchingValue方法在两个地方有调用。
1、在宿主生命周期发生变化的时候。回调LifecycleBoundObserver的onStateChanged方法。最后会调到这个方法,传入this(LifecycleBoundObserver);也就是上边分析的流程
2、在setValue的时候调用。传入null;-------------------这个后面会讲解

下面进入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;
        }
        //判断观察者的最新版本号如果不小于LiveData的当前版本号,那么观察者的数据就是最新,  
        //说明不需要更新,直接退出方法
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        //将livedata版本号赋值给observer最新版本号
        observer.mLastVersion = mVersion;
            // 回调 onChanged方法就是我们监听到数据源发生改变做的处理逻辑了。
        observer.mObserver.onChanged((T) mData);
    }

LiveData有一个版本号,观察者也有一个最新版本号。当LiveData的数据发生变化,版本号+1,每次更新观察者的数据时,会将观察者的最新版本号置为LiveData的当前版本号。所以两者相等,则表示观察者拿到的数据是最新的。
所以这里就会,否则就将最后版本号的值值为LiveData的当前版本号,再更新数据,更新数据就是调用observeronChanged方法。

总结:

注册的流程:

LiveData(observe) ---》 LifecycleRegistry(addObserver)---》ObserverWithState(dispatchEvent)---》LifecycleBoundObserver(onStateChanged)     ---》ObserverWrapper (activeStateChanged)---》LiveData(dispatchingValue)---》LiveData(considerNotify)---》Observer(onChanged)最终就到数据的onChange回调了。

再看看LiveData更新数据时的过程setValue和postValue

//LiveData.java
protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    //从工作线程切换到UI线程,通过创建一个Handler关联到主线程的Looper,
    //调用了post方法提交一个Runnable,切换到主线程去执行run方法中的逻辑
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}



//单例模式,返回一个ArchTaskExecutor对象        
public static ArchTaskExecutor getInstance() {
    if (sInstance != null) {
        return sInstance;
    }
    synchronized (ArchTaskExecutor.class) {
        if (sInstance == null) {
            sInstance = new ArchTaskExecutor();
        }
     }
    return sInstance;
}


@Override
public void postToMainThread(Runnable runnable) {
    if (mMainHandler == null) {
        synchronized (mLock) {
            if (mMainHandler == null) {
                //创建一个关联到主线程Looper的Handler
                mMainHandler = createAsync(Looper.getMainLooper());
            }
        }
    }
    //noinspection ConstantConditions
    mMainHandler.post(runnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        //还是调用setValue
        setValue((T) newValue);
    }
};

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

postValue最终会调用setValue,UI线程中一般使用的是setValue(),而在非UI线程中我们必须使用postValue()。dispatchValue方法开始已经在上面分析过了。

总结

发送数据时的流程:

LiveData(setValue/postValue)---》LiveData(dispatchingValue)                                      --->LiveData(considerNotify)--->Observer(onChanged)

多多批评指正吧~

最后

以上就是欣慰绿茶为你收集整理的LiveData详解的全部内容,希望文章能够帮你解决LiveData详解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部