LiveData是一种可被观察的数据存储器类。与常规的可观察类不同,LiveData可以观察生命周期,从而使它只有在组件处于活跃生命周期状态时通知观察者。
一、使用
LiveData对象通常存储在ViewModel对象中,并可通过getter方法进行访问,如以下示例中所示:
1、创建LiveData对象
public class NameViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> currentName;
public MutableLiveData<String> getCurrentName() {
if (currentName == null) {
currentName = new MutableLiveData<String>();
}
return currentName;
}
}
2、添加观察者
public class MainActivity extends AppCompatActivity {
private NameViewModel model;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取ViewModel
model = new ViewModelProvider(this).get(NameViewModel.class);
// 添加与生命周期有关的监听
model.getCurrentName().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI, in this case, a TextView.
Log.v("AAAAA", "onChange newName:" + newName);
}
});
// 添加与生命周期无关的监听
model.getCurrentName().observeForever(new Observer<String>() {
@Override
public void onChanged(String newName) {
// Update the UI, in this case, a TextView.
Log.v("AAAAA", "observeForever onChange newName:" + newName);
}
});
}
public void onClick(View view) {
// 改变liveData的值,主线程用set
model.getCurrentName().setValue("LiMing set");
// 改变liveData的值,子线程用post
//model.getCurrentName().postValue("LiMing post");
}
}
二、源码分析
1、注册
1.1、observe
- (1)进行主线程判断
- (2)判断组件的生命周期状态,如果被销毁,直接return
- (3)包装组件和监听者,LifecycleBoundObserver实现了LifecycleEventObserver接口
- (4)处理已经添加过的情况
- (5)给组件添加生命周期监听
public abstract class LiveData<T> {
// 添加观察者
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 确保是主线程
assertMainThread("observe");
// 获取组件的生命周期状态,如果已经销毁,直接return
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);
}
}
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {}
1.2、observeForever
不同于observe,observeForever不需要关注组件的生命周期,因为缺少相关步骤。
- (1)进行主线程判断
- (2)包装监听者,AlwaysActiveObserver
- (3)处理已经添加过的情况
public abstract class LiveData<T> {
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
}
2、通知
2.1、修改内容
public abstract class LiveData<T> {
// 设置value
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);
}
};
// 子线程设置value,通过postValue,到主线程执行,最终还是调用setValue
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
}
2.2、通知
- setValue会调用到dispatchingValue方法,可以看到,传入的参数为null。
- 由于参数为null,dispatchingValue方法走else,遍历mObservers所有包装好的监听者
- considerNotify会判断组件的生命周期状态,看是否触发更新,然后调用onChanged
public abstract class LiveData<T> {
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());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// 判断声明周期状态
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 调用监听者的onChanged
observer.mObserver.onChanged((T) mData);
}
}
2.3、递归调用处理
由2.2已经知道livedata的分发流程,它内部也对递归调用修改值做了处理;如下代码,最终打印结果为1、2、2。
liveData.observeForever(new Observer<String>() {
@Override
public void onChanged(String s) {
Log.v("AAAAA", "AAAAA:" + s);
if ("1".equals(s)) {
liveData.setValue("2");
}
}
});
liveData.observeForever(new Observer<String>() {
@Override
public void onChanged(String s) {
Log.v("AAAAA", "AAAAA:" + s);
}
});
liveData.setValue("1");
下方为执行流程分析:
1、首次setValue(1),进入dispatchingValue();
2、if判断mDispatchingValue == false;不执行代码;
3、mDispatchingValue = true,mDispatchInvalidated == false,进入do while;
4、遍历观察者,通过considerNotify,回调onChanged方法;
5、触发setValue(2),进入dispatchingValue();
6、if判断mDispatchingValue == true,修改mDispatchInvalidated == true,return;
7、回到considerNotify执行完毕,mDispatchInvalidated == true,触发break;
8、由于mDispatchInvalidated == true触发while循环,走第二次分发流程,分发value == 2。
3、粘性事件
3.1、生命周期状态监听
还有一种情况,当没有添加监听时,就设置value,之后再添加监听。包装类LifecycleBoundObserver可以监听组件生命周期,在生命周期变化时,会触发onStateChanged,最终通过dispatchingValue(this)进行分发。
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// 当前状态为destroy,移除监听关系
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
// 当前为活跃状态,尝试同步数据
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
3.2、分发
由于initiator不为null,直接走considerNotify进行分发。
public abstract class LiveData<T> {
void dispatchingValue(@Nullable ObserverWrapper initiator) {
...
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
...
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
}
三、注意
- 粘性事件只会响应最后一次的变化
- 可以使用livedata做总线
- 多线程情况下,高并发调用postValue,可能会只修改mPendingData的值,而把中间的某些值丢失。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
网友评论