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等
相关推荐
alexhilton19 小时前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
冬奇Lab1 天前
InputManagerService:输入事件分发与ANR机制
android·源码阅读
日月云棠1 天前
各版本JDK对比:JDK 25 特性详解
java
张小潇1 天前
AOSP15 Input专题InputManager源码分析
android·操作系统
用户8307196840821 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide1 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家1 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java
花花无缺1 天前
搞懂new 关键字(构造函数)和 .builder() 模式(建造者模式)创建对象
java
用户908324602731 天前
Spring Boot + MyBatis-Plus 多租户实战:从数据隔离到权限控制的完整方案
java·后端
桦说编程1 天前
实战分析 ConcurrentHashMap.computeIfAbsent 的锁冲突问题
java·后端·性能优化