基本使用
通常情况下Jetpack组件都是混合一起使用的,这里我们为了讲解,可能会单独使用。
这一篇我们来看一下liveData的使用,livedata特点如下:
-
LiveData是一个具有生命周期感知特性的可观察的数据保持类,使用LiveData保存数据时,在每次订阅或数据更新时会自动回调设置的观察者从而更新数据,真正的实现了数据驱动的效果。
-
LiveData的创建基本会在ViewModel中,从而使数据在界面销毁时继续保持。
-
LiveData 认为观察者的生命周期处于STARTED状态或RESUMED状态下,表示观察者处于活动状态,LiveData只通知活跃的观察者更新数据。
-
注册一个实现该LifecycleOwner 接口的对象配对的观察者,当相应Lifecycle对象的状态改变为DESTROYED时移除观察者
一般LiveData通常跟ViewModel配合使用,也可以单独使用,为了简单起见,这里不配合 ViewModel。
public class LiveDataActivity extends AppCompatActivity {
private TextView textView;
private MutableLiveData<String> currentName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_name);
textView = findViewById(R.id.textView);
currentName = new MutableLiveData<>();
currentName.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
textView.setText(s);
}
});
new Thread(){
@Override
public void run() {
super.run();
for(;;){
SystemClock.sleep(1000);
currentName.postValue(SystemClock.elapsedRealtime()+"");
}
}
}.start();
}
}
这里MutableLiveData是LiveData的一个子类,通过 observe 方法可以订阅修改数据的通知,通过 postValue() 或者 setValue() 方法可以更新数据,已经订阅的 Observer 能够得到数据更改的通知,也即回调 onChanged() 方法。
原理分析
使用超级简单,我们来分析LiveData原理。先从observe开始:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//如果是 DESTROYED 的状态则忽略
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//把 Observer 用 LifecycleBoundObserver 封装起来
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);
}
LifecycleBoundObserver
这里把observer包装成了LifecycleBoundObserver,并且和LifecycleOwner建立的关联。
LifecycleBoundObserver是抽象类ObserverWrapper子类,并且实现了LifecycleEventObserver接口,可以监听lifecycle的回调。在 onStateChanged() 方法里处理了生命周期改变的事件,当接收到 DESTROYED 的事件会自动解除跟 owner 的绑定,如果当前状态是active就将下个流程交给了 activeStateChanged() 。
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() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// 生命周期改变,回调函数
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 生命周期改变,如果是 DESTROYED 就自动解除
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);
}
}
activeStateChanged()
在 activeStateChanged() 方法里,处理了 onActive() 跟 onInactive() 回调的相关逻辑处理,并且调用了dispatchingValue(this)。
void activeStateChanged(boolean newActive) {
//如果状态一样就返回
if (newActive == mActive) {
return;
}
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);
}
}
dispatchingValue
如果使用的是setValue & postValue,那么ObserverWrapper则为空,会通知所有active的Observer。
如果是生命周期的改变,则不为空,只会通知跟该 Owner 绑定的 Observer。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 正在分发时则直接返回
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// 生命周期改变后会调用这里
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else { // 使用setValue或者是postValue时执行这里
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
considerNotify
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 这里为了避免最经典的ABA问题,使用了版本控制
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 更新数据
observer.mObserver.onChanged((T) mData);
}
总结
LiveData 基于观察者模式,并且可以感知生命周期,这使得我们使用 LiveData 既可以享受观察者模式带来的隔离数据与 UI 等强大的解耦能力,还可以享受感知生命周期带来的巨大便利。并且还无需担心内存泄露这个令人头疼的问题。
我们可以使用 LiveData 非常轻松地做到一些非常高效的操作,如仅在 active 的状态下刷新 UI,可以避免不必要的数据刷新。