一、介绍

1、LiveData

LiveData是一种可调查的数据存储器类。与常规的可调查类不同,LiveData具有生命周期感知才能,意指它遵循其他运用组件(如ActivityFragmentService的生命周期。这种感知才能可保证LiveData仅更新处于活泼生命周期状况的运用组件调查者。 假如调查者(由Observer类表明)的生命周期处于STARTEDRESUMED状况,则LiveData会认为该调查者处于活泼状况。LiveData只会将更新告诉给活泼的调查者。为调查LiveData目标而注册的非活泼调查者不会收到更改告诉。

2、ViewModel

ViewModel 类旨在以注重生命周期的办法存储和管理界面相关的数据。首要作用是对数据状况的持有和维护。能够用来解决以下两个问题:

  • Activity装备更改重建时(比方屏幕旋转)保留数据

  • UI组件(Activity与Fragment、Fragment与Fragment)间完成数据共享

ViewModel通常与LiveData这个数据驱动器结合在一起运用。将用于更新界面的 LiveData 目标存储在 ViewModel 目标中,而不是将其存储在 Activity 或 Fragment 中,原因如下:

  • 避免 Activity 和 Fragment 过于庞大。界面控制器只负责显示数据,不负责存储数据状况。

  • LiveData 实例与特定的 Activity 或 Fragment 实例分脱离。这样 LiveData 目标在装备更改后能够持续存在。

LiveData供给感知lifecycle生命周期的数据告诉才能,viewModel作为存储LiveData避免被宿主毁掉的容器

二、基本运用

1、LiveData运用

1)创立LiveData目标

MutableLiveData<String> liveData = new MutableLiveData<>();

2)调查LiveData目标

经过observe办法来监听LiveData的数据变化,每当LiveData产生变化时,都会回调onChanged办法,并返回值的内容

liveData.observe(this, new Observer<String>() {    @Override    public void onChanged(String s) {        //更新UI    }});

3)更新LiveData目标

经过LiveDatasetValue办法,给LiveData赋值,每次赋完值后,都会回调onChanged办法。假如是在异脚步线程中更新数据,在主线程更新监听,则需要调用postValue办法。

liveData.postValue("a");liveData.setValue("b");

2、结合ViewModel运用

1)在ViewModel中存储LiveData目标

public class PtListViewModel extends ViewModel {private final MutableLiveData<List<SupposeItem>> supposeListLiveData = new MutableLiveData<>();    public MutableLiveData<List<SupposeItem>> getSupposeListLiveData() {        return supposeListLiveData;    }    public void setSupposeList(List<SupposeItem> list){        supposeListLiveData.setValue(list);    }}

2)在Activity的onCrete阶段调查LiveData

final PtListViewModel mViewModel =  new ViewModelProvider(mContext).get(PtListViewModel.class);		mViewModel.getSupposeListLiveData().observe(mContext, supposeItems -> ());

每当有值产生变化时,就会收到最新值的告诉。一旦运用组件处于 STARTED 状况,就会从它正在调查的 LiveData 目标接纳最新值

3)更新LiveData值

能够结合网络请求或许需要在不同Fragment之间传递某些状况/筛选值时,经过setValue或postValue传值

new ViewModelProvider(JobInfoListFragmentActivity.this).get(PtListViewModel.class).setSupposeList(bean.data);

三、原理解析

1、注册监听observer()

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

调用observer()时,传递了两个参数,第一个是LifecycleOwner接口实例,第二个参数Observer就是咱们调查的回调。接下来将这两个参数传递new出了一个新的目标:LifecycleBoundObserver,最后将LifecycleBoundObserverLifecycleOwner进行了绑定。

2、LifecycleBoundObserver

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {        @NonNull        final LifecycleOwner mOwner;        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {            super(observer);            mOwner = owner;        }        @Override        boolean shouldBeActive() {            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);        }        //Activity生命周期变化时,回调办法        @Override        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            //destroy状况解绑,能够避免内存走漏
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {                removeObserver(mObserver);                return;            }            //只要是Active状况才会去更新livedata            activeStateChanged(shouldBeActive());        }        @Override        boolean isAttachedTo(LifecycleOwner owner) {            return mOwner == owner;        }        //解除监听        @Override        void detachObserver() {            mOwner.getLifecycle().removeObserver(this);        }    }

能够看到这里面与LifecycleOwner进行了绑定,而且完成了onStateChanged办法,当生命周期产生变化时执行activeStateChanged(shouldBeActive());办法;shouldBeActive() 返回了 要求生命周期至少是STARTED状况才被认为是activie状况;假如state是DESTROYED状况时,则移除调查者,在 Activity、Fragment的生命周期走到 onDestroy 的时候,就会取消订阅,避免内存走漏。

3、dispatchingValue()

持续追寻activeStateChanged办法发现,在里面做了一些活泼状况值的操作,而且当状况活泼时,更新数据值。

void activeStateChanged(boolean newActive) {            if (newActive == mActive) {                return;            }            // immediately set active state, so we\'d never dispatch anything to inactive            // owner            mActive = newActive;....            if (mActive) {                dispatchingValue(this);            }        }
void dispatchingValue(@Nullable ObserverWrapper initiator) {    ...    //遍历LiveData的一切调查者执行下面代码    for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {                    considerNotify(iterator.next().getValue());                    if (mDispatchInvalidated) {                        break;                    }                }    ...}//将数据值回调到livedata.observer()回去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);    }

能够看到当状况从不活泼到活泼状况,产生状况改变时。会遍历一切注册的调查者,判别数据version<=最新数据version(数据产生变化),就会调用调查者的onChanged来告诉数据产生变化。

4、用户主动调用setValue()/postValue()

@MainThread    protected void setValue(T value) {        assertMainThread("setValue");        mVersion++;        mData = value;        dispatchingValue(null);    }
private final Runnable mPostValueRunnable = new Runnable() {        @SuppressWarnings("unchecked")        @Override        public void run() {            Object newValue;            synchronized (mDataLock) {                newValue = mPendingData;                mPendingData = NOT_SET;            }            setValue((T) newValue);        }    };

postValue()在子线程更新数据,经过Hander做了线程切换,终究调用setValue办法。而setValue中就是调用了上面剖析的 dispatchingValue告诉调查者。

5、LiveData 的observeForever办法

这个办法比observe办法少一个LifecycleOwner参数,为啥呢?因为这个办法不需要感知生命周期,需要在setValue 值更新时立马收到回调。

6、LiveData的数据倒灌问题

倒灌现象:

先给LiveData设置了value,然后监听者才开端对LiveData进行监听,这时LiveData的value会立马回调给监听者

原因:

LiveData每次setValue或postValue时mVersion都会自增(见上文setValue源码),当调用LiveData进行observe时,终究会调到如下办法

private void considerNotify(ObserverWrapper observer) {        ...                if (observer.mLastVersion >= mVersion) {            return;        }        observer.mLastVersion = mVersion;        observer.mObserver.onChanged((T) mData);    }

当observer的mLastVersion小于mVersion时就会把之前的数据回调给监听者,observer的mLastVersion的初始值为-1

static final int START_VERSION = -1;...int mLastVersion = START_VERSION;

当咱们setValue时,mVersion会从-1开端自增,之后咱们去observe时,因为observer的mLastVersion的初始值是-1,比mVersion=0小,所以调用observe时,会立马把旧的数据回调给调查者。

参考资料:

developer.android.com/topic/libra…

developer.android.com/topic/libra…