LiveData的使用

1
2
3
4
5
6
7
8
9
val livedata = LiveData<Int>()
//发送数据
livedata.setValue()//立即生效,只能在主线程调用
livedata.postValue()//通过Handler转到主线程,有丢失数据的风险,可以用来在子线程调用
//观察数据
void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
livedata.observe(this) {}
//第一个参数是一个`LifecycleOwner`对象,这个让LiveData具有与生命周期绑定的能力。
//第二个参数是一个`Observer`,是一个回调

LiveData的使用是十分的简单的,其原理也并不复杂。

observe方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@MainThread  //@MainThread 意味着必须在主线程调用它(我想这个与LiveData的使用场景有很深的联系,LiveData常常是用传递UI数据的,而UI必须在主线程更新)
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//若生命周期已经走到DESTROYED就不需要再继续了
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//包装一下
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//observer与lifecycle一一对应,同一个observer不允许重复添加,通过lamba表达式添加的不是同一个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); //将包装类添加为lifecycle的观察者
}

接下来看看是怎么与生命周期绑定的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {  
@NonNull
final LifecycleOwner mOwner;

LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
//判断当前生命周期是否大于STARTED,是就是活跃的
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//这个是生命周期变化的回调方法
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// DESTROYED状态移除observer
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
// 当生命周期发生变化更新LiveData的活跃状态
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}

@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}

@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}

---LiveData---
//将observer从LiveData的列表移除的同时,移除lifecycle的observer,且将活跃状态变为false
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
removed.detachObserver();
removed.activeStateChanged(false);
}

void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner mActive = newActive;
//记录LiveData活跃观察者的数量
changeActiveCounter(mActive ? 1 : -1);
//在LiveData活跃状态下立刻分发值
if (mActive) {
dispatchingValue(this);
}
}

void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return; }
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
// observer转成活跃状态立刻分发一次值
considerNotify(initiator);
initiator = null;
} else {
//遍历observer分发值
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}

//回调observer的onChanged方法
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;
}
//比较LiveData与Observer对象维护的版本号,一致就不在分发新值
//若不一致,回调onChanged分发新值(对于初始化的observer,其版本号为-1,只要LiveData中更
//新过版本号,那新的observer总是会在初始化后收到最新的值)
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}

在执行了observer()方法后,会将observer与lifecycle关联起来,当observer处于活跃状态才会给其分发值,而当observer由非活跃状态转为活跃状态,会立刻为其分发一次值。这一机制保证了Activity销毁重建后立刻会受到最新的值(粘性事件)。

setValue方法

1
2
3
4
5
6
7
8
9
@MainThread  
protected void setValue(T value) {
assertMainThread("setValue");
//维护的版本号
mVersion++;
mData = value;
//通知所有的观察者
dispatchingValue(null);
}

postValue方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
protected void postValue(T value) { 
//代表是否有post任务正在执行
boolean postTask;
synchronized (mDataLock) {
//设置postTask=true,在这条post真正执行之前,后续的post都会直接return被丢弃
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
//执行任务中,丢弃后续的post
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
//post任务执行完毕,将mPendingData = NOT_SET,可继续新的post任务
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};

@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}

public class DefaultTaskExecutor extends TaskExecutor {
//最终执行mPostValueRunnable的地方
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
//创建了一个主线程Handler
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
}

从上面我们不难看出,postValue()是可能会在连续post的时候丢弃值,从LiveData使用场景来看,UI数据的变化往往只有收到最新的就OK了,这个并不影响LiveData传递UI数据。但是若是在需要密集连续传递数据的地方,需要避免使用postValue(),采用setValue方法或者选用其他的组件。

粘性事件

粘性事件的优势是毋庸置疑的,在注册新的observer就会收到最新数据,避免了开始新的Activity还需要手动获取一次数据。
但是有优点就有缺点,在一些场景下并不适用粘性事件,那要怎样解决这个问题呢。
方案一:粘性事件的原理核心就是LiveData和observer所维护的版本号,因此可以初始化observer的时候使两者相等即可。因为LiveData维护的版本号是私有的,因此若想实现这个的效果,得使用反射。
方案二:SingleLiveEvent,这个原理也十分简单,SingleLiveEvent维护了一个信号量,AtomicBoolean mPending = new AtomicBoolean(false)
setValue置为true,意为有新值,在observer.onChanged时消耗掉。这样就实现了当添加一个新observer时,信号量为false,无法发送最新的值,也就失去了粘性。