LiveData 源码解析

LiveData 是什么

基于观察者模式

LiveData 是一种数据持有类,并且可以在给定的生命周期中对数据进行观察。意味着观察者可以和生命周期持有者成对添加。

感知生命周期

和其他可被观察的类不同的是,LiveData 是有生命周期感知能力的,这意味着它可以在 activities, fragments, 或者 services 生命周期是活跃状态(STARTED 或 RESUMED)时更新这些组件。

自动解除数据订阅

要想使用 LiveData(或者这种有可被观察数据能力的类)就必须配合实现了 LifecycleOwner 的对象使用。在这种情况下,当对应的生命周期对象 DESTORY 时,才能移除观察者。这对 Activity 或者 Fragment 来说显得尤为重要,因为他们可以在生命周期结束的时候立刻解除对数据的订阅,从而避免内存泄漏等问题。

源码解析

observe 订阅

observe(LifecycleOwner, Observer) 方法

方法的关键逻辑放在了注释中。

/**
 * 在 owner 生命周期内添加 observer。事件在主线程上调度。
 * 如果 LiveData 已经有了数据,将会被发送到 observer 上。
 * <p>
 * observer 只会在 owner 状态为 {@link Lifecycle.State#STARTED} 
 * 或 {@link Lifecycle.State#RESUMED} 的活跃状态时接收事件。
 * <p>
 * 如果在 owner 到达 {@link Lifecycle.State#DESTROYED} 状态,observer 会自动被移除。
 * <p>
 * 在 owner 非活跃状态时发生数据变化,它将不会接收任何更新。
 * 当它重新回到活跃状态,它将自动获取最后一次有效的数据。
 * <p>
 * LiveData 在 LifecyclerOwner 未销毁期间会一直强引用着 observer 和 owner。
 * 在 LifecyclerOwner 被销毁后会移除对 observer 和 owner 的引用。
 * <p>
 * 如果 owner 已经处于 {@link Lifecycle.State#DESTROYED} 状态,LiveData 会忽略这次操作。
 * <p>
 * 如果 wrapper(owner、observer) 在映射已经存在,LiveData 会忽略这次操作。
 * 如果 observer 已经绑定了其他的 owner,LiveData 抛出 {@link IllegalArgumentException}。
 */
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    assertMainThread("observe");
    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);
}
LifecycleBoundObserver

ObserverWrapper 是 LiveData 内部的 Observer 包装类,而 LifecycleBoundObserver 继承了它并且实现了 LifecycleEventObserver 接口,使其能监听到生命周期的变化。

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(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        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);
    }
}

private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;
    
    ObserverWrapper(Observer<? super T> observer) {
        mObserver = observer;
    }
    
    /**
     * 是否将当前生命周期状态视为活跃状态
     */
    abstract boolean shouldBeActive();
    
    /**
     * 是否已经依附了 LifecycleOwner
     */
    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }
    
    /**
     * 解绑 observer
     */
    void detachObserver() {
    }
    
    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        // 立即改变活跃状态,这样就不会分发事件给非活跃 owner
        mActive = newActive;
        // mActiveCount 是 LiveData 全局变量,用于判断多少个 observer 处于活跃状态。
        // wasInactive 用于判断了上次 LiveData 是否处于非活跃状态
        boolean wasInactive = LiveData.this.mActiveCount == 0;
        LiveData.this.mActiveCount += mActive ? 1 : -1;
        if (wasInactive && mActive) {
            // 活跃 observer 数量从 0 到 1 时回调
            onActive();
        }
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            // 活跃 observer 数量从 1 到 0 时回调
            onInactive();
        }
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

有关dispatchingValue(ObserverWrapper)方法的源码放在 setValue(Object) 分析。

mObservers.putIfAbsent(observer, wrapper)

observe(LifecycleOwner, Observer) 方法中有一句 ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);,mObservers 是一个 SafeIterableMap 类型的映射,来看看它的部分源码:

public V putIfAbsent(@NonNull K key, @NonNull V v) {
    Entry<K, V> entry = get(key);
    if (entry != null) {
        return entry.mValue;
    }
    put(key, v);
    return null;
}

protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
    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;
}

可以看到内部是一个非线程安全的链表存储键值对,putIfAbsent(K, V)通过 key 去查找映射内是否有对应的 value,如果存在则直接返回,不存在就放入新的数据并返回空。

observeForever(Observer)
/**
 * 和 {@link LiveData#observe(LifecycleOwner, Observer)} 类似,
 * 但是一直保持 active,意味着它会接收所有事件并且不会被自动移除。
 * 可以手动调用 {@link #removeObserver(Observer)} 来停止对 LiveData 的监听。
 * 当 LiveData 有这种 observer,将被视为 active。
 * <p>
 * 当 observer 已经和 owner 绑定,LiveData 会抛出 {@link IllegalArgumentException} 异常。
 */
@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);
}

setValue 发送

setValue(Object) 方法
/**
 * 设置值。如果有活跃的 observer 则将值分发给它们。
 * <p>
 * 该方法必须在主线程执行。如果需要后台执行,使用 {@link #postValue(Object)}
 */
@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

mVersion 变量初始值为 -1,每次 setValue(Object) 都会自增 1,相当于记录最新数据的版本。

dispatchingValue(ObserverWrapper) 方法
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    // mDispatchingValue 是为了解决并发调用 dispatchingValue 的情况
    if (mDispatchingValue) {
        // mDispatchInvalidated == true 时会让下面的 while 循环再执行一次
        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;
}

该方法出现在两个地方,一个是 LifecycleOwner 生命周期发生变化时,另一个是 setValue(Object) 时。

considerNotify(ObserverWrapper) 方法
private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    // 在分发之前检查最后的状态。因为有可能状态已经改变但我们还没有接收到事件。
    //
    // 我们仍然先检查 observer.active 来让它作为一个事件的入口。 
    // 所以即使 observer 变为活跃状态,如果我们还没有接收到事件,
    // 我们最好不要去通知,以便保持一个可预测的通知顺序。
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    //noinspection unchecked
    observer.mObserver.onChanged((T) mData);
}

observer 的 mLastVersion 初始值也为 -1,用于判断当前监听的数据是 LiveData 数据的哪个版本,当 mLastVersion 小于 mVersion 说明当前监听的数据不是最新,才会去回调 onChanged(Object)

通知流程

从上面的源码可以看出注册 observer 后有两种情况:

  1. 生命周期发生变化:
    1. observe(LifecycleOwner, Observer) 方法中 owner 注册了 observer
    2. owner 生命周期发生变化时调用 onStateChanged(LifecycleOwner, Lifecycle.Event)
    3. observer.activeStateChanged(boolean)
    4. dispatchingValue(ObserverWrapper),这里只传当前 observer
    5. considerNotify(ObserverWrapper),内部调用了 observer.onChanged(Object)
  2. 设置 LiveData 的数据(setValue(Object)postValue(Object)):
    1. observe(LifecycleOwner, Observer) 方法中 mObservers 映射添加了 observer
    2. setValue(Object) 时调用了 dispatchingValue(null)
    3. 对 mObservers 做循环,对每个 observer 调用 considerNotify(ObserverWrapper),内部调用了 observer.onChanged(Object)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LiveData 是用于在 Android 应用程序中观察数据的一个组件。LiveData 是一个可观察的数据持有者类,它具有生命周期感知能力,因此它会自动管理它与 Activity 和 Fragment 生命周期的关系,从而可以避免内存泄漏和崩溃。 LiveData 的一个重要特性是它可以通知观察者数据已更改。当 LiveData 的值发生更改时,它会自动通知所有观察者。这意味着您无需手动更新 UI 或执行其他操作以反映数据更改。LiveData 还支持数据转换和过滤,因此您可以将原始数据转换为 UI 可以直接使用的格式。 LiveData 使用观察者模式进行数据监听,您可以使用 `observe()` 方法将观察者添加到 LiveData 实例中,该方法需要传入一个 LifecycleOwner 和一个 Observer 对象。LifecycleOwner 表示 LiveData 与哪个组件的生命周期绑定,通常是 Activity 或 Fragment。Observer 对象定义了当 LiveData 的值更改时要执行的操作。 下面是一个简单的示例,演示如何使用 LiveData 监听数据更改: ``` // 创建一个 LiveData 实例 val myLiveData = MutableLiveData<String>() // 将观察者添加到 LiveData 实例中 myLiveData.observe(this, Observer { newValue -> // 在这里更新 UI 或执行其他操作 textView.text = newValue }) // 更改 LiveData 的值 myLiveData.value = "Hello World" ``` 在上面的示例中,我们创建了一个名为 `myLiveData` 的 LiveData 实例,并将其与当前组件的生命周期绑定。我们还将一个 Observer 对象传递给 `observe()` 方法,以便在 LiveData 的值更改时执行操作。当我们调用 `myLiveData.value = "Hello World"` 时,LiveData 会自动通知所有观察者,以便更新 UI 或执行其他操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值