添加依赖:
implementation "android.arch.lifecycle:livedata:2.2.0"
在上一篇中简单的说了下ViewModel的使用和对源码简单分析了下,这里接着说LiveData的使用和源码分析。
google官网是这样描述LiveData的,LiveData是一种可观察的数据存储器类,和常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如Activity、Fragment或Service)的生命周期,这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。
通过上面的描述会得到一点:LivaData只会将更新通知给活跃的观察者,为观察LiveData对象而注册的非活跃观察者不会收到更改通知的。这样在activity或者fragment中使用时,就不必担心页面销毁时因无法释放而造成泄漏,系统会立即退订注册的观察者。
使用LiveData的优势:
确保界面符合数据状态
LiveData遵循观察者模式,当底层数据发生变化时,LiveData会通知Observer对象进行页面的更新;
不会发生内存泄漏
观察者会绑定到Lifecycle对象,并在其关联的生命周期遭到销毁后进行自我清理;
不会因activity的停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的activity),则它不会接收任何LiveData事件;
不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察,LiveData将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化;
数据始终保持最新状态
如果生命周期变为非活跃状态,它会再次变为活跃状态时接收最新的数据;例如,曾经在后台的activity会在返回前台后立即接收最新的数据。
适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了activity或者fragment,它会立即接收最新的可用数据;
共享资源
可以使用单例模式扩展LiveData对象以封装系统服务,以便在应用中共享它们;
LiveData既然有这么多优势,开发中必须的使用起来,在使用时,避免activity和fragment过于庞大,LiveData一般和ViewModel一起使用,activity和fragment负责页面数据的展示,LiveData和ViewModel负责数据的存储状态;
public class MyViewModel extends ViewModel {
private static final String TAG = MyViewModel.class.getSimpleName();
private MutableLiveData<String> currentName;
public MutableLiveData<String> getCurrentName() {
if (currentName == null) {
currentName = new MutableLiveData<>();
}
return currentName;
}
@Override
protected void onCleared() {
super.onCleared();
Log.d(TAG, "ViewModel has destory");
}
}
LiveData是一个抽象类,MutableLiveData是系统提供的一个它的子类,一般使用的时候就用MutableLiveData;
public class ViewModelActivity extends BaseActivity {
private static final String TAG = ViewModelActivity.class.getSimpleName();
private ActivityViewmodelBinding binding;
private MyViewModel myViewModel;
@Override
protected ViewBinding getViewBinding() {
binding = ActivityViewmodelBinding.inflate(getLayoutInflater());
return binding;
}
@Override
protected void initData() {
super.initData();
//实例化ViewModel对象
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
myViewModel.getCurrentName().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
//进行更新ui或者其他逻辑
Log.d(TAG, "s===" + s);
}
});
}
@Override
protected void initView() {
super.initView();
binding.updateData.setOnClickListener(v -> {
myViewModel.getCurrentName().setValue("数据刷新了");
});
}
}
在数据需要更新的时候调用setValue进行设置,然后会通过观察者通知,最终回调到onChanged的方法中,在onChanged方法中进行页面刷新或者其他逻辑即可;
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//检测当前添加观察者所处的线程,不能在background thread中使用
assertMainThread("observe");
//如果当前的生命周期是Destory就直接返回,不会进行观察者的注册
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将接收LiveData 的callback和Lifecycle生命周期进行绑定 将Observer变成有生命周期的LifecyleBoundObserver
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//获取已经存在Observer 如果是每次都创建一个 existing肯定是null的
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);
}
observe方法的第一个参数是LifecycleOwner,这是一个拥有activity生命周期的接口,在ComponentActivity中就实现了该接口,Observer是一个接收LiveData的callback接口;看到会进行所在线程的检测,也就是LiveData不能在background thread中使用;在前面提到过LiveData只会对活跃状态的页面进行通知更新,非活跃状态的不会通知更新,如果是destory时,直接不会让注册观察者了;在LifecycleBoundObserver中通过Lifecycle生命周期的监听来管理Observer的移除,这样LiveData也就拥有的生命周期,同时也避免了因为页面的销毁而造成泄漏。
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() {
//判断Observer是否处于活跃状态 getCurrentState 获取的是State
//State是一个枚举 定义了DESTROYED INITIALIZED CREATED STARTED RESUMED 这些Observer状态
//而对于Observer处于STARTED 和RESUMED状态时 LiveData才会认为观察者处于活跃状态 这个时候才会将更新通知给到观察者
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//活跃状态的监听回调
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//DESTROYED 时会移除掉注册的Observer
removeObserver(mObserver);
return;
}
//活跃状态的改变
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
//是否进行绑定
return mOwner == owner;
}
@Override
void detachObserver() {
//解绑Observer 会直接移除对应的Observer
mOwner.getLifecycle().removeObserver(this);
}
}
通过onStateChanged时时监听Observer的活跃状态,
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
//如果当前状态和之前一致 就不做处理
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
//更新observer状态
mActive = newActive;
//mActiveCount Observer活跃的次数
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) {
//处于活跃时LiveData通知Observer进行消息更新
dispatchingValue(this);
}
}
如果Observer处于活跃状态时,会调用dispatchingValue进行消息更新,
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//在添加Observer时 initiator是不为null
considerNotify(initiator);
initiator = null;
} else {
//调用setValue方法重新设置时,initiator传入的是null
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
不管initiator是不是null,最终都会调用considerNotify进行消息的刷新,
private void considerNotify(ObserverWrapper observer) {
//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.
//再次检查Observer的状态 防止状态的改变
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//版本的判断
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
//调用onChanged方法 将需要更新的消息回传回去
observer.mObserver.onChanged((T) mData);
}
到这里会看到最终调用了onChanged方法,也就是在上面activity中使用时重写的onChanged方法了,
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
会将Observer实例对象作为key,LifecycleBoundObserver实例对象作为value,缓存在双向链表结构的容器中,这样的目的就是在后面如果要使用到Observer时,直接从缓存中获取,就不需要进行重新注册,
public V putIfAbsent(@NonNull K key, @NonNull V v) {
//通过observer对象实例key获取Entry实例
Entry<K, V> entry = get(key);
if (entry != null) {
//如果存在就直接返回ObserverWrapper实例 在第一次时entry都是为null的,
return entry.mValue;
}
//进行数据的保存
put(key, v);
return null;
}
protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
//创建Entry实例 Entry是一个双向链表结构的实体
Entry<K, V> newEntry = new Entry<>(key, v);
mSize++;
if (mEnd == null) {
mStart = newEntry;
mEnd = mStart;
return newEntry;
}
mEnd.mNext = newEntry;
newEntry.mPrevious = mEnd;
mEnd = newEntry;
return newEntry;
}
这里需要注意,第一次时ObserverWrapper实例肯定是null,要调用后面的addObserver添加观察者,后面继续调用oberver的话,ObserverWrapper实例存在并添加到当前的生命周期中时,不会注册新的观察者。找到Lifecycle子类LifecycleRegistry中的addObserver方法;
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
//获取当前的状态
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//将Observer和当前的状态进行绑定
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//将当前绑定状态的Observer保存在一个HashMap中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
//获取当前所处的生命周期 如果已经不存在了直接返回
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//计算目前的活跃状态
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
//判断是否为活跃状态 并且Observer是否添加到了缓存中
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
//通过分发监听状态
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//监听状态的改变
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
这样就完成了活跃状态的监管,只需要更新活跃Observer消息即可,
观察者注册好后,调用setValue或者postValue后,在onChanged会调中就可以更新ui等操作了,
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
其实还是调用了dispatchingValue方法对需要更新的消息进行派发更新。
网友评论