0. 介绍
LiveData, 同属于 JetPack 构建集合, 根据文档描述 LiveData 是一个可观察的数据持有者类. 与常规 observable 不同, LiveData 是生命周期感知的, 这意味着它尊重其他应用程序组件的生命周期, 例如 Activity,Fragment 或 Service. 此感知确保 LiveData 仅更新处于活动生命周期状态的应用程序组件观察者.
优势(以下摘自 google 文档, google 翻译了一下)
(1)确保您的 UI 符合您的数据状态
LiveData 遵循观察者模式. 生命周期状态更改时, LiveData 会通知 Observer 对象. 您可以合并代码以更新这些 Observer 对象中的 UI. 每次应用程序数据更改时, 您的观察者都可以在每次更改时更新 UI, 而不是更新 UI.
(2)没有内存泄漏
观察者绑定到 Lifecycle 对象并在其相关生命周期被破坏后自行清理.
由于停止活动而没有崩溃
如果观察者的生命周期处于非活动状态(例如, 在后端堆栈中的活动的情况下), 则它不会接收任何 LiveData 事件.
(3)不再需要手动生命周期处理
UI 组件只是观察相关数据, 不会停止或恢复观察. LiveData 自动管理所有这些, 因为它在观察时意识到相关的生命周期状态变化.
(4)始终保持最新数据
如果生命周期变为非活动状态, 则会在再次变为活动状态时接收最新数据. 例如, 后台活动在返回前台后立即收到最新数据.
(5)适当的配置更改
如果由于配置更改 (例如设备轮换) 而重新创建活动或片段, 则会立即接收最新的可用数据.
(6)共享资源
您可以使用单例模式扩展 LiveData 对象以包装系统服务, 以便可以在应用程序中共享它们. LiveData 对象连接到系统服务一次, 然后任何需要该资源的观察者都可以只观看 LiveData 对象.
1. 使用
- class MainActivity : AppCompatActivity() {
- val curName: MutableLiveData<String> by lazy {
- MutableLiveData<String>()
- }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- curName.observe(this, Observer<String> {
- println("value is $it")
- })
- curName.value="old value"
- }
- }
使用很简单, 当 MutableLiveData 对象的 value 发生改变时会出发 Observer 的 onChanged 方法, 其中 MutableLiveData 继承自 LiveData.
2. 目的
(1)LiveData 如何进行生命周期感知
(2)如何更新事件
(3)如何避免内存泄漏
3. 分析
3.1LiveData 如何进行生命周期感知
先看一下 LiveData 的 observer 方法
- @MainThread
- public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
- 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);
- }
看最后一行, owner.getLifecycle().addObserver(wrapper);owner 就是咱们用的 Activity 或者 Fragment, 这就和上一篇文章 Lifecycle 对应上了
Android Lifecycle 源码分析 -- 源码阅读 100 天(1) https://juejin.im/post/5bf3cb46f265da612239f612 , 这里添加的监听者就是 LifecycleBoundObservr, 这个类实现了 LifecycleObserver, 这就是感应的生命周期的方式.
3.2 如何更新事件
说实话, 这个控件就是个观察者模式, 事件的 Observer 就是这个 LifecycleBoundObserver, 看看这个对象的 onStateChanged 方法
- @Override
- public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
- if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
- removeObserver(mObserver);
- return;
- }
- activeStateChanged(shouldBeActive());
- }
看一下 activieStageChanged 方法
- void activeStateChanged(boolean newActive) {
- if (newActive == mActive) {
- return;
- }
- // immediately set active state, so we'd never dispatch anything to inactive
- // owner
- 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 方法, 看一下这个方法
- private 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<T>, ObserverWrapper>> iterator =
- mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
- considerNotify(iterator.next().getValue());
- if (mDispatchInvalidated) {
- break;
- }
- }
- }
- } while (mDispatchInvalidated);
- mDispatchingValue = false;
- }
如果 ObserverWrapper 参数不为 null, 就调用 considerNotify 方法, 否则就遍历 mObservers, 调用 considerNotify, 那就看一下这个方法
- 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;
- }
- observer.mLastVersion = mVersion;
- //noinspection unchecked
- observer.mObserver.onChanged((T) mData);
- }
首先判断 ObserverWrapper 是否需要被激活, 如果需要被激活就调用 activeStateChanged 方法, 否则就调用 我们自定义的 Observer 的 onChanged((T) mData)方法.
3.3 如何避免内存泄漏
回到 onStateChanged 的方法里调用的 activeStateChanged(shouldBeActive()), 看一下 shouldBeActive 方法
- @Override
- boolean shouldBeActive() {
- return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
- }
- public boolean isAtLeast(@NonNull State state) {
- return compareTo(state)>= 0;
- }
这个方法就是将当前的 state 和 STARTED 进行对比, 如果是 STARTED 或者 RESUMED 状态, 那么传入 activeStateChanged 的参数就是 true, 否则就是 false, 再回看 activeStateChanged 方法
- void activeStateChanged(boolean newActive) {
- if (newActive == mActive) {
- return;
- }
- // immediately set active state, so we'd never dispatch anything to inactive
- // owner
- 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);
- }
- }
- }
当状态没有改变时, 直接返回, 否则根据 newActive 进行判断是否为 activt 状态,
- if (wasInactive && mActive) {
- onActive();
- }
- if (LiveData.this.mActiveCount == 0 && !mActive) {
- onInactive();
- }
之后根据 mActive 和 activeCount 调用 onActive 和 onInactive 方法. 这就一目了然了, 当生命周期调用 onStart 之后, 就处于激活状态, onstop 之后就处于非激活状态, 这样数据改变时也就不会走到 Observer 的方法了, 从而避免了内存泄漏.
来源: http://www.jianshu.com/p/ee5c1cd8e403