深入理解Android Jetpack的LiveData原理

253 阅读3分钟

深入理解Android Jetpack的LiveData原理

LiveData是Android Jetpack库的重要组成部分,是一个可观察的数据持有类。它的设计旨在解决Android应用中数据管理和生命周期管理的问题。本文将详细介绍LiveData的工作原理,帮助你更好地理解和使用这一强大的工具。

什么是LiveData?

LiveData是一个生命周期感知的可观察类,用于持有数据。它的核心特性是能够在Activity或Fragment的生命周期内自动管理数据更新,从而避免内存泄漏和无效的UI更新。这种特性使得LiveData在Android开发中尤为有用。

核心概念

可观察的数据持有者

LiveData持有一个数据对象,并允许多个观察者(通常是Activity或Fragment)观察这个数据对象的变化。当数据发生变化时,LiveData会通知所有处于活跃状态的观察者。

生命周期感知

LiveData知道它的观察者的生命周期状态。只有当观察者处于活跃状态(即STARTED或RESUMED)时,LiveData才会发送更新。这确保了UI组件只有在能够接收更新时才会更新,防止了不必要的UI更新和潜在的崩溃。

观察者模式

LiveData采用观察者模式。当数据发生变化时,它会通知所有活跃状态的观察者。这种模式非常适合用于处理异步数据流,如数据库查询或网络请求的结果。

LiveData的实现原理

类结构

LiveData的实现依赖于多个类和接口,其中最核心的是LiveData类本身。以下是LiveData类的简化结构:

java
复制代码
public abstract class LiveData<T> {
    private static final Object NOT_SET = new Object();
    private final Object mDataLock = new Object();
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
    private int mActiveCount = 0;

    // 其他成员变量和方法

    public void observe(LifecycleOwner owner, Observer<? super T> observer) {
        // 省略实现细节
    }

    public void observeForever(Observer<? super T> observer) {
        // 省略实现细节
    }

    public void removeObserver(Observer<? super T> observer) {
        // 省略实现细节
    }

    public void removeObservers(LifecycleOwner owner) {
        // 省略实现细节
    }

    protected void setValue(T value) {
        // 省略实现细节
    }

    protected void postValue(T value) {
        // 省略实现细节
    }

    private void dispatchingValue(ObserverWrapper initiator) {
        // 省略实现细节
    }

    // 其他方法
}

观察者模式的实现

LiveData中,观察者是实现了Observer<T>接口的对象。当数据变化时,ObserveronChanged(T t)方法会被调用。

为了管理观察者及其生命周期,LiveData内部使用了一个ObserverWrapper类来包装每个观察者:

java
复制代码
private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;
    int mLastVersion;

    ObserverWrapper(Observer<? super T> observer) {
        mObserver = observer;
        mLastVersion = START_VERSION;
    }

    abstract boolean shouldBeActive();

    boolean activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return false;
        }
        mActive = newActive;
        return true;
    }

    void detachObserver() {
        // 省略实现细节
    }
}

生命周期感知的实现

LiveData通过LifecycleOwner接口来感知观察者的生命周期。每个观察者在注册时都需要提供一个LifecycleOwnerLiveData使用它来跟踪观察者的生命周期状态。

java
复制代码
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    if (owner.getLifecycle().getCurrentState() == Lifecycle.State.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);
}

private 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(Lifecycle.State.STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }
}

数据更新的实现

LiveData提供了两种更新数据的方法:setValue(T value)postValue(T value)

  • setValue(T value) :在主线程上设置新值,并通知所有活跃的观察者。
  • postValue(T value) :在后台线程上设置新值,最终会在主线程上更新。
java
复制代码
protected void setValue(T value) {
    synchronized (mDataLock) {
        mData = value;
        mVersion++;
    }
    dispatchingValue(null);
}

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

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;
}

使用示例