本文只分析 Livedata 好处、原理实现,用法用处不再赘述(官网啥都有 😎)。
官方文档连接(需翻墙)
一、LiveData 介绍
Livedata 是 Google 推荐的 Android 架构组件之一,是一个存放可被观察的数据持有类,但与一般的被观察者不同的是,它是有生命周期感知功能,解决了android开发者需要去手动处理生命周期的痛点。
比如之前用 Retrofit+Rxjava处理接口回调数据,需要自己去处理 activity 或 fragment 生命周期,以解决 onStop 或 onDestory之后回调数据的问题。现在只需要 Retrofit+Livedata 就好,其他的 Livedata 帮你做了。
二、Livedata 优点
英文水平有限,避免误人我还是把官网原文搬过来一下吧。
以下是看完官网后的个人理解,并不是完全的翻译。
1、Ensures your UI matches your data state(不知道怎么翻译):
LiveData follows the observer pattern. LiveData notifies Observer
objects when the lifecycle state changes. You can consolidate your code to update the UI in these Observer
objects. Instead of updating the UI every time the app data changes, your observer can update the UI every time there's a change.
Livedata 遵循观察者模式,并且 Livedata 会在生命周期变化的时候通知观察者。
它优雅的处理了生命周期问题,并不会所有的数据变化都会回调,所以你可以在他回调时大胆的做更新 UI操作。
2、No memory leaks(没有内存泄漏):
Observers are bound to Lifecycle
objects and clean up after themselves when their associated lifecycle is destroyed.
观察者都是绑定Lifecycle的, Lifecycle destory 的话,会销毁自己。
Lifecycle也是架构组件之一,了解请看我的另一篇专门介绍连接
3、No crashes due to stopped activities(activity stop之后,不会崩溃)
If the observer's lifecycle is inactive, such as in the case of an activity in the back stack, then it doesn’t receive any LiveData events.
Livedata 把 activity 生命周期合并分成了inactive与active两种状态(start 与 resume 为 active,其他为inactive)。处于非活 inactive 状态的话,是不会收到 Livedata 任何事件的。
4、No more manual lifecycle handling(不需要手动管理生命周期):
UI components just observe relevant data and don’t stop or resume observation. LiveData automatically manages all of this since it’s aware of the relevant lifecycle status changes while observing.
UI 组件只需要关心相关的数据,不需要去手动变换生命周期状态,Livedata 已经帮你搞定了。
5、Always up to date data():
If a lifecycle becomes inactive, it receives the latest data upon becoming active again. For example, an activity that was in the background receives the latest data right after it returns to the foreground.
简单来说,Livedata 在生命周期非活状态inactive,数据发生变化的话,变成活状态active的时候,会回调一次最终的数据。
6、Proper configuration changes:
If an activity or fragment is recreated due to a configuration change, like device rotation, it immediately receives the latest available data.
像屏幕旋转导致的 activity 或 fragment重创建之后,Livedata 会立即通知一下相应的观察者。保证了数据不会丢失。
7、Sharing resources
You can extend a LiveData
object using the singleton pattern to wrap system services so that they can be shared in your app. The LiveData
object connects to the system service once, and then any observer that needs the resource can just watch the LiveData
object. For more information, see Extend LiveData.
这个怎么说呢
三、Livedata 如何实现这些功能,源码分析
又到了大家最喜欢的 Read the fucking source code 环节。好找在Livedata 源码不多,而且容易理解
1、如何做到生命周期感知:
这里涉及到LifecycleOwner属于另一个架构组件 lifecycle,可参考我的另一篇lifecycle专讲。
不了解的话也没关系,只需要知道lifecycle可以提供activity 或 fragment 当前的生命周期状态,并且状态是可以被观察的。
首先从Livedata添加观察者的方法 observe 开始:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing.owner != wrapper.owner) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
第一个参数为LifecycleOwner用于提供当前的生命周期状态,DESTROYED的时候不做任何操作。
第二个为观察者observer,首先把observer包装成了LifecycleBoundObserver这是一个一会分析。然后把LifecycleBoundObserver维护到mObservers里:
private SafeIterableMap<Observer<T>, LifecycleBoundObserver> mObservers =
new SafeIterableMap<>();
mObservers是一个LinkedList结构的容器 通过putIfAbsent方法判断,容器中此观察者是不是已经存在,如果存在且LifecycleOwner不同的话则抛异常,LifecycleOwner相同则 return 不重复添加。
wrapper 也就是LifecycleBoundObserver实现了LifecycleObserver是 lifecycle 的观察者所以最后添加到 lifecycle 的观察中。
再来揭晓LifecycleBoundObserver:
class LifecycleBoundObserver implements GenericLifecycleObserver {
public final LifecycleOwner owner;
public final Observer<T> observer;
public boolean active;
public int lastVersion = START_VERSION;
LifecycleBoundObserver(LifecycleOwner owner, Observer<T> observer) {
this.owner = owner;
this.observer = observer;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(observer);
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
}
void activeStateChanged(boolean newActive) {
if (newActive == active) {
return;
}
active = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += active ? 1 : -1;
if (wasInactive && active) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !active) {
onInactive();
}
if (active) {
dispatchingValue(this);
}
}
}
答案就在这里
此类实现了GenericLifecycleObserver 即 为lifecycle 的观察者,通过上文的 observe方法添加到了lifecycle观察中,
通过此类持有 Livedata 的观察者observer,当 生命周期发生变化时 会回调onStateChanged方法,然后 Livedata 的观察者在onStateChanged中执行相应的逻辑。
再来看onStateChanged具体逻辑:
第一个判断就搞定了 二、2、No memory leaks(没有内存泄漏)功能点:如果生命周期是 destory 的话,移除观察者。
然后通过isActiveState方法,把所有生命周期划分成两类 inactive 与 active
static boolean isActiveState(State state) {
return state.isAtLeast(STARTED);
}
State为枚举:
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
通过compareTo方法 isAtLeast为 true 的话至少是STARTED或RESUMED。
接着执行activeStateChanged
void activeStateChanged(boolean newActive) {
if (newActive == active) {
return;
}
active = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += active ? 1 : -1;
if (wasInactive && active) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !active) {
onInactive();
}
if (active) {
dispatchingValue(this);
}
}
通过巧妙的设计实现了:
1、状态没有变化,什么也不做。
2、变为活(active)就是调用onActive(),非活(inactive)就调用onInactive().
3、另外,变为活的话就调用dispatchingValue方法,此方法为回调观察者的方法。即 二、5、Always up to date data,非活变为活,会立即回调一次数据(如果数据发生变化的话情况下)。
2、事件的通知
LiveData通过 setValue 或 postValue 方法去改变持有的数据,并通知观察者,最终都是调用dispatchingValue()方法:
private void dispatchingValue(@Nullable LifecycleBoundObserver initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
这一些列的判断 ,目前我还没有领悟是为了什么!!!
最终通过调用considerNotify:
private void considerNotify(LifecycleBoundObserver observer) {
if (!observer.active) {
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 (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
observer.activeStateChanged(false);
return;
}
if (observer.lastVersion >= mVersion) {
return;
}
observer.lastVersion = mVersion;
//noinspection unchecked
observer.observer.onChanged((T) mData);
}
代码很简单,先判断下,最终的数据有没有通知过,没有的话直接 observer。
分析完毕!
网友评论