LiveData
是androidx.lifecycle-livedata包下的一个抽象类,实现了一种关联了生命周期的简单观察者模式,主要的功能就是用于视图层与数据间的单向一对多通知,一个LiveData
会持有一个可观察的Data对象,一开始是处于NOT_SET
状态,当用户经过setValue方法更新后,LiveData
会遍历全部的observer(处于Active状态的),通知他们Data的更新.LiveData
的行为会在Lifecycle
范围内,避免不少Activity Leak和空指针//声明一个LiveData
val data:MutableLiveData<String> = MutableLiveData()
//在须要的地方订阅,observer的onChange方法会回调
data.observe(lifecycleOwner,observer)
//能够和retrofit配合使用
interface ApiService {
@GET("/api/get")
fun getChannels():LiveData<ApiResponse<Page<Media>>>
}
//能够和room配合使用
@Dao
interface BorrowModelDao {
@Query("select * from s_borrow_moel")
fun getAllBorrowedItems(): LiveData<List<BorrowModel>>
}
//配合ViewModel保存数据/监听数据更改
class MyViewModel:ViewModel(){
val data:MutableLiveData<String> = MutableLiveData()
}
复制代码
private val userLiveData:MutableLiveData<User> = MutableLiveData()
val userNames:LiveData<String> = Transformations
.map(userLiveData){
user ->
user.name
}
复制代码
Transformations在androidx.lifecycle包下java
//声明
val mediatorLiveData:MediatorLiveData<String> = MediatorLiveData()
//其余合适的地方添加source
mediatorLiveData.addSource(stringFromNetwork){
mediatorLiveData.value = it
}
mediatorLiveData.addSource(stringFromDatabase){
mediatorLiveData.value = it
}
复制代码
ViewModel
能够在一个LifecycleOwner
的onCreate
到OnDestroy
之间保存实例不受到屏幕旋转等ConfigChange的影响Activity/Fragment
持有ViewModel
,而ViewModel
持有各种LiveData
,Activity/Fragment
注册观察须要的数据,实现数据与UI的同步,并且不会所以发生Activity
泄漏,甚至能够用ViewModel
来进行Activity/Fragment
之间的通信LifecycleOwner
: Activity/Fragment
都是LifecycleOwner
(support包下的AppCompatActivity和对应的Fragment),他是androidx.lifecycle:lifecycle-common包下的一个借口,只有getLifecycle()一个方法,返回一个Lifecycle对象Lifecycle
: 而这个Lifecycle
就是维护生命周期state的主体,默认实现是LifecycleRegistry
,这个提及来也挺长的,之后有空再新的文章里仔细说明,反正如今读者只要知道咱们经常使用的AppCompatActivity/Fragment
都是能够拿到生命周期Lifecycle的就好了LifecycleObserver
: 也是一个接口,不过它一个抽象方法也没有,若是咱们须要一个新的自定义的观察 者,只要实现这个接口,而后在须要对应生命周期方法回调的方法上添加OnLifecycleEvent
注解并添加对应注解就行了,LiveData
有一个 LifecycleBoundObserver
内部类实现了这个接口,不过继承关系是这样的 LifecycleObserver
<--GenericLifecycleObserver
<- LifecycleBoundObserver
,LifecycleBoundObserver
会在onStateChange
收到回调,不依赖于注解,不过读 者如今只要知道在Lifecycle
中state
发生改变的时候,LifecycleObserver
会收 到通知(void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
)LifecycleBounderObserver
,和不带的AlwaysActiveObserver
..abstract class LiveDate{
class LifecycleBounderObserver extends ObserverWrapper implements GenericLifecycleObserver{
}
private abstract ObserverWrapper{
}
private class AlwaysActiveObserver extends ObserverWrapper {
}
}
复制代码
LifecycleOwner
, Observer
类(简单的回调通知接口)LifecycleOwner
获取Lifecycle
,判断时候是DESTROYED
状态,是的话直接return 将Observer
和LifecycleOwner
包装为LifecycleBoundObserver
对象SafeIterableMap<Observer<? super T>, ObserverWrapper>
对象mObservers,保存了Observer和对应的Wrapper,存入LifecycleBoundObserver对象后判断是否已存在而且是否对应当前LifecycleOwner,作出相应的处理,当mObservers中没有时,直接给LifecycleOwner的Lifecycle注册该LifecycleBoundObservermActive
,而后经过LiveData类的mActivieCount是否为0来判断是否是彻底没有通知过,若是是进入非active状态mActiveCount就-1,不然+1,原先未active如今active了,调用onActive
方法,新的mActivieCount == 0
而且 新active的状态为false就调用onInactive
方法,而后判断mActive
,true则会调用dispatchValue方法,基本上mActivieCount只会有0 -> 1 ,1 -> 0两个状态变化,因此onActive
是LiveData观察者数量从无到有时回调,onInactive
反之private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
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);
}
}
复制代码
} ```android
onActive
方法,反之会走onInactive
方法,无论原先状态如何,只要新状态是活跃就会走dispatchValue
onInactive/onActive
是LiveData
里两个open protected的方法,只在MediatorLiveData里有实现,我尚未仔细研究MediatorLiveData,你们能够去看看源码LiveData
的dispatchValue
方法,传入的参数为ObserverWrapper
,也就是LifecycleBoundObserver的父类(LifecycleBoundObserver
继承了ObserverWrapper
,实现了GenericLifecycleObserver
),在这要注意下内部类(非静态)是能够拿到外部类实例的,LiveData.this.XXX,忘记的同窗复习下,我是很久没用java,忽然看到有点懵逼..//传入参数是Observer,有的话就分发给它,为null就对全部Observers分发数据
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());
//标记为无效时会跳出循环,在while循环中等待一次mDispatchInvalidated再次变为true时再次进入for循环
if (mDispatchInvalidated) {
break;
}
}
}
//没有被标记无效时while循环就执行一次完事,不然会再次执行
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
复制代码
LiveData
中的mDispatchingValue/mDispatchInvalidated
在此处保证不会重复分发或者分发旧的value,当setValue
分发调用dispatchValue(null)
时会遍历全部的Observer分发新值,不然只分发给传入的ObserverWrapper
,这里说明下:LiveData
维护了mDispatchingValue/mDispatchInvalidated
,而Observer可能会有多个,都持有LiveData对象(由于是内部类),因此等待的observer对应的LiveData
会得到mDispatchInvalidated = true
,中断进行中的分发,让旧数据再也不分发considerNotify
: 第一步检查ObserverWrapper
是否mActive
,第二步检查shouldBeActive()
,第三步检查ObserverWrapper
的版本observer.mLastVersion >= mVersion
,最后才通知更新,调用Observer的onChange方法ObserverWrapper
中的mActive
用来控制该观察者是否须要分发(activeStateChanged(boolean)
方法的做用下)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);
}
复制代码
很简单的逻辑,就是
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
复制代码
mActive会在生命周期变化时会被屡次检查
2. 第二步再次检查`shouldBeActive()`状态
3. 第三步检查`mLastVersion`和`mVersion`
这个version是在setValue时被+1的,检查一下防止重复分发,完成后修改lastVersion而后回调`onChange(T)`
复制代码
按惯例先看看代码,postValue的代码也好理解,只是给赋值操做加了一个锁,并把setValue放到主线程执行,使多个postValue只有最后一个的value生效api
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
复制代码
想象一下若是两个线程T-A
,T-B
里都执行了postValue传入不一样的值A,B,先会在方法内的mDataLock锁住的代码块竞争执行,好比A先执行,mPendingData
先被赋值为A,postTask
=> true,而后赋值为B,也就是说第一次的赋值才会经过同步块以后的if判断,执行分发runnable,线程T-B
只是修改了mPendingValue
的值app
而后会有一个主线程上的同步代码块(也是同一个锁),将新值执行setValue
,mPendingValue
重设为初始值,也就是说取得值其实是后一个线程的B,后面分发完成重设为NOT_SET
,后面的PostValue又进入原来的逻辑了ide
postValue的注释也很清楚了: If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched.工具
LiveData的结构是比较简单的,使用时注意不要屡次注册观察者,通常若是在Activity中使用,就在OnCreate方法注册,Activity被关闭或回收后观察者会自动解除订阅,因此不会发生泄漏,咱们也能够本身继承LiveData作更多的定制来实现本身的业务逻辑,配合Tranformations工具类和MediatorLiveData能够实现不少比较复杂的逻辑post