Android LiveData 全面解析:使用Java构建响应式UI【源码篇】

目录

[一、LiveData 核心特性概述](#一、LiveData 核心特性概述)

[二、LiveData 核心源码解析](#二、LiveData 核心源码解析)

[2.1 MutableLiveData](#2.1 MutableLiveData)

[2.2 LiveData](#2.2 LiveData)

[2.2.1 构造函数:初始化状态](#2.2.1 构造函数:初始化状态)

[2.2.2 setValue():同步更新](#2.2.2 setValue():同步更新)

[2.2.3 postValue():异步更新](#2.2.3 postValue():异步更新)

[思考:mPostValueRunnable 在主线程为什么也需要synchronized](#思考:mPostValueRunnable 在主线程为什么也需要synchronized)

[2.2.4 dispatchingValue():数据分发](#2.2.4 dispatchingValue():数据分发)

(1)循环判断

(2)分发通知

[2.2.5 considerNotify():智能通知](#2.2.5 considerNotify():智能通知)

(1)三层过滤

[2.2.6 observe()方法:建立观察关系](#2.2.6 observe()方法:建立观察关系)

(1)重复注册的两种情况

[2.2.7 LifecycleBoundObserver构造](#2.2.7 LifecycleBoundObserver构造)

(1)状态判断:shouldBeActive()

(2)生命周期监听:onStateChanged()

[2.2.8 ObserverWrapper基类](#2.2.8 ObserverWrapper基类)

三、扩展内容

3.1数据获取与移除

[3.1.1 getValue():获取当前数据](#3.1.1 getValue():获取当前数据)

[3.1.2 removeObserver():移除观察者](#3.1.2 removeObserver():移除观察者)

[3.1.3 removeObservers():清除所有观察者](#3.1.3 removeObservers():清除所有观察者)

[3.2 无生命周期绑定的观察者](#3.2 无生命周期绑定的观察者)

[3.2.1 observeForever()](#3.2.1 observeForever())

[3.2.2 AlwaysActiveObserver实现](#3.2.2 AlwaysActiveObserver实现)


系列入口导航:Android Jetpack 概述

LiveData是一个可观察的数据持有者类,具有生命周期感知能力,这意味着它遵循其他应用组件(如Activity、Fragment)的生命周期。这种感知能力确保LiveData只更新处于活跃生命周期状态的应用组件观察者。我们在上一章了解了 LiveData 一些基本用法,本章我们结合上一篇文章提到的方法,来聊聊实现的源码逻辑。

一、LiveData 核心特性概述

  • 生命周期感知:自动管理观察者的生命周期

  • 性数据一致:确保UI与数据状态匹配

  • 无内存泄漏:观察者绑定到Lifecycle对象,在销毁后自动清理

  • 配置更改后自动更新:Activity因配置更改重建后立即接收最新数据

二、LiveData 核心源码解析

我们在上一章了解了,LiveData 是一个抽象类,而 MutableLiveData 是 LiveData 的子类。我们看看 MutableLiveData 具体实现了什么。

2.1 MutableLiveData

java 复制代码
public class MutableLiveData<T> extends LiveData<T> {
    public MutableLiveData(T value) {
        super(value);
    }

    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}
  • 两个构造函数,解释了为什么可以通过 new MutableLiveData<>("初始值") 直接设置初始值
  • 方法可见性改变 : 这是最核心的设计!父类 LiveData 中这两个方法是 protected 的,而 MutableLiveData 将它们重写为public。

2.2 LiveData

LiveData本身是一个持有数据的被观察者容器,首先看下它的核心代码结构:

java 复制代码
public abstract class LiveData<T> {
    // 数据持有容器
    private volatile Object mData;
    static final int START_VERSION = -1;
    // 观察者容器(使用SafeIterableMap保证迭代安全)
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();
    // 数据版本号
    private int mVersion;
    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
            }
            setValue((T) newValue);
        }
    };
    public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }
    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }
    private void considerNotify(ObserverWrapper observer) {
        //通知观察者之前需要确定观察者处于活跃状态
        if (!observer.mActive) {
            return;
        }
        //通知观察者之前需要确定观察者的数据版本
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //通知观察者数据更新
        observer.mObserver.onChanged((T) mData);
    }
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        // 循环遍历观察者
        for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
             mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
            considerNotify(iterator.next().getValue());
        }
    }
    //观察者注册
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        // 关键代码①
        // 注册对Lifecycle的观察,用以监听观察者所在组件的生命周期
        owner.getLifecycle().addObserver(wrapper);
    }
    protected void setValue(T value) {
        //同步更新数据
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
    protected void postValue(T value) {
        //异步更新数据
        synchronized (mDataLock) {
            mPendingData = value;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        //移除观察者监听
        ObserverWrapper removed = mObservers.remove(observer);
        removed.detachObserver();
        removed.activeStateChanged(false);
    }
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {

        final LifecycleOwner mOwner;
        // 判断当前观察者是否处于活跃状态
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        // 关键代码②
        //监听观察者所在组件的生命周期变化
        public void onStateChanged(@NonNull LifecycleOwner source,
                                   @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                // 监听生命周期组件是否被销毁
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                // 循环直至生命周期状态同步
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        int mLastVersion = START_VERSION;
                                boolean mActive;
        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }
        void activeStateChanged(boolean newActive) {
            // 观察者活跃状态未变化时直接返回
            if (newActive == mActive) {
                return;
            }
            // 更新观察者活跃状态
            mActive = newActive;
            // 如果是从非活跃状态转换为活跃状态,则立即触发一次数据更新流程
            // 从而确保观察者能拿到最新的数据
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
}
fun interface Observer<T> {
    fun onChanged(value: T)
}

上面的代码我省略的部分,下面分析具体功能时,会补全对于代码!!!

LiveData 是一个抽象类,上面的代码有点多,我们一点点分解,它的核心成员变量/常量有四个

  • mData 用以存储可变化的数据
  • mObservers 存储所有观察者
  • mVersion 标记当前数据mData的版本号
  • START_VERSION 数据的初始版本号

2.2.1 构造函数:初始化状态

java 复制代码
public abstract class LiveData<T> {
    // 静态常量
    static final Object NOT_SET = new Object();
    static final int START_VERSION = -1;
    
    // 无参构造函数
    public LiveData() {
        mData = NOT_SET;      // 数据初始状态:未设置
        mVersion = START_VERSION; // 版本号:-1
    }
    
    // 带初始值的构造函数
    public LiveData(T value) {
        mData = value;                  // 设置初始数据
        mVersion = START_VERSION + 1;   // 版本号:0
    }
}

这里先了解下初始值,无参的版本号为 -1,有参的版本号为 0,后续再看具体有什么作用。

2.2.2 setValue():同步更新

java 复制代码
@MainThread
protected void setValue(T value) {
    // 1. 严格的主线程检查
    assertMainThread("setValue");
    
    // 2. 递增版本号(每更新一次数据,版本号+1)
    mVersion++;
    
    // 3. 存储新数据
    mData = value;
    
    // 4. 开始分发数据
    dispatchingValue(null);  // null表示分发给所有观察者
}

2.2.3 postValue():异步更新

java 复制代码
volatile Object mPendingData = NOT_SET;

protected void postValue(T value) {
    boolean postTask;
    
    // 1. 线程安全地设置待处理数据
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;  // 检查是否已有待处理数据
        mPendingData = value;                // 存储数据
    }
    
    // 2. 避免重复提交任务
    if (!postTask) {
        return;
    }
    
    // 3. 切换到主线程执行
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

// 主线程任务
private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        
        // 4. 获取待处理数据(线程安全)
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;  // 清空待处理标记
        }
        
        // 5. 调用setValue完成最终更新
        setValue((T) newValue);
    }
};

实现了从后台线程安全地更新数据并在主线程通知观察者的功能,最终仍然调用的 setValue 。

  • volatile 保证 mPendingData 的内存可见性(一个线程修改,其他线程立即可见)
  • synchronized保证操作原子性(不会有两个线程同时修改)
java 复制代码
synchronized (mDataLock) {
    postTask = mPendingData == NOT_SET;  // 判断是否已有数据在等待处理
    mPendingData = value;                // 将新值存入暂存区
}

目的:多个后台线程可能同时调用 postValue(),需要线程安全地存储数据

  • mPendingData == NOT_SET:检查暂存区是否为空。如果为空(true),说明这是第一个待处理数据,需要提交任务如果不为空(false),说明已有数据在等待,不需要重复提交
  • mPendingData = value:无论暂存区是否为空,都用最新值覆盖旧值(数据合并)

之后通过 ArchTaskExecutor.getInstance().postToMainThread 切回到主线程后读取覆盖后mPendingData 中的值,调用setValue 更新数据。

思考:mPostValueRunnable 在主线程为什么也需要synchronized

虽然 mPostValueRunnable 的 run() 方法确实在主线程执行,但它的代码会和后台线程并发访问同一个变量 mPendingData

java 复制代码
// 场景:后台线程正在执行 postValue()
postValue("新数据") {  // 后台线程
    synchronized (mDataLock) {          // 后台线程持有锁
        // 正在执行:mPendingData = "新数据";
        // 假设执行到一半...
    }
}

// 同一时刻,主线程执行 run()
mPostValueRunnable.run() {  // 主线程
    // 如果没有 synchronized,这里可以同时访问 mPendingData!
    newValue = mPendingData;    // ❌ 可能读到不一致状态
    mPendingData = NOT_SET;     // ❌ 可能打断后台线程的写入
}

由此看来两个 synchronized的作用是不同的。

  • 第一个 synchronized (在 postValue 中) :防止多个后台线程同时调用 postValue() 时产生冲突。

  • 第二个 synchronized (在 mPostValueRunnable 中) :防止后台线程执行 postValue时影响主线程正在执行的读取-清空操作

2.2.4 dispatchingValue():数据分发

接下来我们回到 setValues 使用到的 dispatchingValue(null)。

java 复制代码
private boolean mDispatchingValue;
@SuppressWarnings("FieldCanBeLocal")
private boolean mDispatchInvalidated;

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<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                
                // 如果在分发过程中被标记为无效,重新开始
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    
    mDispatchingValue = false;
}
(1)循环判断

这个方法围绕两个布尔类型:mDispatchingValuemDispatchInvalidated

  • mDispatchingValue :**状态标记, 是否处于分发过程**中。
  • mDispatchInvalidated中断请求, 当前分发是否已经过时需要重来。

在看源码的时候,发现 mDispatchInvalidated用的很妙。分两种场景来分析下:

第一次调用:

  1. do-while 会先执行一次,如果中途没被打断,mDispatchInvalidated 保持 false,循环结束

分发期间再次触发 setValue :

  1. 此时 mDispatchingValue = true (正在分发值), 标记 mDispatchInvalidated = true 同时退出第二次调用
  2. 第二次调用 return 后,控制权回到第一次调用的循环中首先会 break 当前的分发,此时while 循环条件:true,所以会重新执行do块!
(2)分发通知

根据 initiator 是否为 null 分为两种情况:

针对性通知(initiator != null)

java 复制代码
if (initiator != null) {
    considerNotify(initiator);  // 只通知特定的观察者
    initiator = null;
}

触发场景 :观察者的生命周期状态变化,只通知特定的一个。当观察者从非活跃变为活跃时,需要立即获得最新数据。

这里只接触到了为空的情况,不为空的针对性通知在后续的源码中会有所体现

广播通知模式 (initiator == null)

java 复制代码
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
    
    considerNotify(iterator.next().getValue());  // 通知每个观察者
    
    if (mDispatchInvalidated) {
        break;  // 关键:如果被标记无效,中断当前遍历
    }
}

触发场景 :数据值更新时(setValue()/postValue()),需要通知所有活跃的观察者。

  • 使用 iteratorWithAdditions():即使在遍历过程中有新的观察者注册,也能被包含

2.2.5 considerNotify():智能通知

java 复制代码
private void considerNotify(ObserverWrapper observer) {
    // 1. 检查观察者是否活跃
    if (!observer.mActive) {
        return;  // 非活跃状态,不通知
    }
    
    // 2. 再次检查生命周期状态(可能在此期间发生了变化)
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);  // 更新为非活跃
        return;
    }
    
    // 3. 关键:版本号检查(避免重复通知)
    if (observer.mLastVersion >= mVersion) {
        return;  // 观察者已持有最新版本数据
    }
    
    // 4. 更新观察者的版本号
    observer.mLastVersion = mVersion;
    
    // 5. 最终回调给用户
    observer.mObserver.onChanged((T) mData);
}
(1)三层过滤
  • 第一层: mActive 是 ObserverWrapper 内部维护的状态,这是最快的检查,避免不必要的计算,但是生命周期发生改变后,可能无法及时更新。
  • 第二层: shouldBeActive():根据实际的生命周期状态判断,对于 LifecycleOwner:检查是否至少是 STARTED 状态

为什么需要两次检查? :因为状态可能在第一次检查和现在之间发生了变化(并发场景),当生命周期发生改变的时候,观察者的mActive可能没及时更新

  • 第三层核心机制 :每个 LiveData 有 mVersion,每个观察者有 mLastVersion。在前面看到的mVersion在这里发挥作用了,每次**setValue() 会使 mVersion++ ,**观察者只在 mLastVersion < mVersion 时收到通知。

更新的流程走完了,接下来我们看看观察者的注册流程。

2.2.6 observe()方法:建立观察关系

java 复制代码
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
        new SafeIterableMap<>();

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    // 1. 线程检查:必须在主线程调用
    assertMainThread("observe");
    
    // 2. 生命周期检查:如果已销毁则不注册
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        return;
    }
    
    // 3. 创建包装器:将用户Observer包装为LifecycleBoundObserver
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    
    // 4. 添加到观察者映射表(防止重复添加)
    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;  // 已存在,直接返回
    }
    
    // 5. 关键:注册生命周期监听
    owner.getLifecycle().addObserver(wrapper);
}

这里使用 SafeIterableMap来管理观察者

  • :用户的原始 observer 对象
  • :包装后的LifecycleBoundObserver

普通 HashMap 在迭代时如果修改结构(添加/删除元素)会抛出ConcurrentModificationException。而 SafeIterableMap 允许在迭代时安全地添加/删除元素。上面提到过,在遍历的时候如果有新的观察者注册进来,也是可以分发出去的。有兴趣的可以去了解,这里就不过多解释了。

java 复制代码
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

将用户原始的 Observer 包装为 LifecycleBoundObserver:监听生命周期变化,自动管理观察者的活跃状态。后面再详细探究下。

(1)重复注册的两种情况
java 复制代码
// 情况A:同observer,不同LifecycleOwner → 抛出异常
if (existing != null && !existing.isAttachedTo(owner)) {
    throw new IllegalArgumentException(...);
}

// 情况B:完全相同的注册 → 静默返回
if (existing != null) {
    return;
}

设计意图:避免同一个观察者被多次通知,造成数据重复处理。

最后执行:

java 复制代码
owner.getLifecycle().addObserver(wrapper);

wrapper 开始监听 owner 的生命周期事件;当生命周期变化时,**onStateChanged()**被调用

2.2.7 LifecycleBoundObserver构造

java 复制代码
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    @NonNull final LifecycleOwner mOwner;
    
    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);  // 调用父类构造,设置mObserver = observer
        this.mOwner = owner;
        
        // 初始状态:
        // mActive = false(尚未活跃)
        // mLastVersion = START_VERSION = -1(未接收过数据)
    }
    
    // 判断当前是否应该处于活跃状态
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
    
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        // 步骤1:检查是否销毁
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        if (currentState == DESTROYED) {
            removeObserver(mObserver);// 自动清理
            return;
        }

        // 步骤2:循环更新状态
        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            activeStateChanged(shouldBeActive());// 关键调用!
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner; // 检查是否绑定到指定的owner
    }

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this); // 从生命周期移除监听
    }
}

这个 LifecycleBoundObserver 是 LiveData 实现自动生命周期管理的核心类。它巧妙地将观察者与生命周期绑定,确保数据只在界面可见时更新。首先看看这个类的三重身份

java 复制代码
class LifecycleBoundObserver 
    extends ObserverWrapper           // 1. LiveData观察者包装器
    implements LifecycleEventObserver  // 2. 生命周期事件监听器
{
    @NonNull final LifecycleOwner mOwner;  // 3. 关联的生命周期持有者
}

LifecycleBoundObserver 同时承担了三个不同的角色,分别面向三个不同的系统:

  • ObserverWrapper:面向 LiveData 内部系统,这个在后面会详细讲解
  • LifecycleEventObserver:监听 LifecycleOwner 的生命周期变化
  • LifecycleOwner:提供生命周期状态的来源

LifecycleEventObserver 和 LifecycleOwner 在之前的源码篇有讲解,这里就不多提了。

(1)状态判断:shouldBeActive()
java 复制代码
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

只有当生命周期至少是STARTED(onStart() 之后,onStop() 之前)才活跃,确保数据只在界面对用户可见时更新

(2)生命周期监听:onStateChanged()
java 复制代码
public void onStateChanged(@NonNull LifecycleOwner source,
        @NonNull Lifecycle.Event event) {
    // 步骤1:检查是否销毁
    Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
    if (currentState == DESTROYED) {
        removeObserver(mObserver);  // 自动清理
        return;
    }
    
    // 步骤2:循环更新状态
    Lifecycle.State prevState = null;
    while (prevState != currentState) {
        prevState = currentState;
        activeStateChanged(shouldBeActive());  // 关键调用!
        currentState = mOwner.getLifecycle().getCurrentState();
    }
}
  • 当 Activity/Fragment 执行 onDestroy(),从 LiveData 的观察者列表中移除自己
  • 循环更新状态,直到相同为止,更新状态 activeStateChanged(shouldBeActive());

思考下为什么要使用循环:

原因是当生命周期发生变化时,可能会触发连续的状态变化。 导致第一次获取到的mOwner.getLifecycle().getCurrentState()和在循环中的mOwner.getLifecycle().getCurrentState()两次的值不一样 。这个目的就是追赶最终状态

2.2.8 ObserverWrapper基类

java 复制代码
private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;  // 真正的用户观察者
    int mLastVersion = START_VERSION;     // 该观察者持有的数据版本
    boolean mActive = false;              // 当前是否活跃
    
    ObserverWrapper(Observer<? super T> observer) {
        this.mObserver = observer;
    }
    
    abstract boolean shouldBeActive();  // 由子类实现具体逻辑

    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }

    void detachObserver() {}

    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) { // 状态未变,快速返回
            return;
        }
        mActive = newActive;  // 更新内部状态
        changeActiveCounter(mActive ? 1 : -1);  // 更新活跃计数器
        if (mActive) {  // 变为活跃时的特殊处理
            dispatchingValue(this); // 立即尝试获取最新数据
        }
    }
}

当观察者从非活跃变为活跃 时,activeStateChanged(true) 会立即尝试调用 dispatchingValue 获取最新数据。这就是 Android 配置变化(如屏幕旋转)后界面能自动恢复数据的核心机制。

三、扩展内容

理解了上面介绍的,下面的这些就应该很好理解了。

3.1数据获取与移除

3.1.1 getValue():获取当前数据

java 复制代码
public T getValue() {
    Object data = mData; // 复制到局部变量
    if (data != NOT_SET) {
        return (T) data;
    }
    return null;
}

先复制到局部变量 data,再进行比较和返回。

3.1.2 removeObserver():移除观察者

java 复制代码
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    // 1. 线程检查
    assertMainThread("removeObserver");
    
    // 2. 从映射表中移除
    ObserverWrapper removed = mObservers.remove(observer);
    
    if (removed == null) {
        return;  // 观察者不存在
    }
    
    // 3. 解除生命周期绑定
    removed.detachObserver();
    
    // 4. 更新活跃状态
    removed.activeStateChanged(false);
}

最后一步的 activeStateChanged(false) 就不会执行 dispatchingValue(this)

java 复制代码
void activeStateChanged(boolean newActive) {
    if (newActive == mActive) {
        return;  // 状态未变
    }
    mActive = newActive;
    changeActiveCounter(mActive ? 1 : -1);  // 减少活跃计数器
    
    // 注意:这里不会调用 dispatchingValue(this)
    // 因为是从活跃变为非活跃,不需要分发数据
}

3.1.3 removeObservers():清除所有观察者

java 复制代码
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
    assertMainThread("removeObservers");
    
    // 遍历所有观察者,移除属于指定owner的观察者
    for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
        if (entry.getValue().isAttachedTo(owner)) {
            removeObserver(entry.getKey());
        }
    }
}

3.2 无生命周期绑定的观察者

3.2.1 observeForever()

java 复制代码
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
    // 1. 线程检查
    assertMainThread("observeForever");
    
    // 2. 创建AlwaysActiveObserver(始终活跃)
    AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
    
    // 3. 添加到观察者列表
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    
    // 4. 标记为活跃状态
    wrapper.activeStateChanged(true);
}

3.2.2 AlwaysActiveObserver实现

java 复制代码
private class AlwaysActiveObserver extends ObserverWrapper {
    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }
    
    @Override
    boolean shouldBeActive() {
        return true;  // 始终返回true,表示总是活跃
    }
}

AlwaysActiveObserver 是 LiveData 中用于 observeForever() 的观察者包装器。虽然代码极其简单,但它实现了与 LifecycleBoundObserver 完全不同的行为模式。

核心特性:永远活跃不依附于生命周期

特性 LifecycleBoundObserver AlwaysActiveObserver
创建方式 observe(LifecycleOwner) observeForever()
活跃判断 基于生命周期状态 总是返回 true
生命周期绑定 自动绑定到 LifecycleOwner 无绑定
自动清理 Activity销毁时自动移除 必须手动 removeObserver()
适用场景 UI层数据观察 非UI层、服务、Repository等
相关推荐
常利兵3 小时前
ButterKnife在Android 35 + Gradle 8.+环境下的适配困境与现代化迁移指南
android
组合缺一3 小时前
Solon AI (Java) v3.9 正式发布:全能 Skill 爆发,Agent 协作更专业!仍然支持 java8!
java·人工智能·ai·llm·agent·solon·mcp
MSTcheng.3 小时前
【C++】C++11新特性(二)
java·开发语言·c++·c++11
熊猫钓鱼>_>3 小时前
移动端开发技术选型报告:三足鼎立时代的开发者指南(2026年2月)
android·人工智能·ios·app·鸿蒙·cpu·移动端
一 乐3 小时前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
KIKIiiiiiiii3 小时前
微信个人号API二次开发中的解决经验
java·人工智能·python·微信
80530单词突击赢4 小时前
SpringBoot整合SpringMVC全解析
java·spring boot·后端
vx1_Biye_Design4 小时前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
vx_Biye_Design4 小时前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计