我是靠谱客的博主 自觉小兔子,最近开发中收集的这篇文章主要介绍Jetpack 之 LiveData 源码分析LiveData数据容器可被观察,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

LiveData


LiveData 是一个可以感知 LifecycleOwner 生命周期的可被观察的数据容器。

接下来,我们从 3 个角度来分析 LiveData

  1. 数据容器;
  2. 可被观察;
  3. 感知生命周期

数据容器


LiveData 它实际上是一个数据容器,我们设置的数据真正是存放在 mData 里面的。

static final int START_VERSION = -1;
private static final Object NOT_SET = new Object();
private volatile Object mData = NOT_SET;

public T getValue() {
    Object data = mData;
    if (data != NOT_SET) {
        return (T) data;
    }
    return null;
}

protected void setValue(T value) {
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

可被观察


LiveData 它是可以被观察的数据源。

一个数据可以被观察,那么它内部肯定有一个集合去存放观察者,同时会暴露注册和移除观察者的方法。

private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers = new SafeIterableMap<>();

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
    // ...
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    // 同一个LifecycleObserver 只能 绑定一个 LifecycleOwner
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    // ...
}

@MainThread
public void removeObserver(@NonNull final Observer<T> observer) {
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        return;
    }
    // ...
}

@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
    for (Map.Entry<Observer<T>, ObserverWrapper> entry : mObservers) {
        if (entry.getValue().isAttachedTo(owner)) {
            removeObserver(entry.getKey());
        }
    }
}

感知生命周期


LiveData 是可以感知 LifecycleOwner 的生命周期的。

那其实就是内部给 LifecycleOwner 注册了一个 LifecyclObserver

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
    // 如果生命周期不是活跃的,则不进行观察者的注册
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        return;
    }
    // 这里将 LifecycleOwner 和 Observer 一一对应,保证在不活跃的时候能自动移除掉
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    // ...
    owner.getLifecycle().addObserver(wrapper);
}

然后,在移除 Observer 的时候, 需要将对应的 LifecycleObserverLifecycleOwner 里面移除掉 。

@MainThread
public void removeObserver(@NonNull final Observer<T> observer) {
    ObserverWrapper removed = mObservers.remove(observer);
    // ...
    removed.detachObserver();
    removed.activeStateChanged(false);
}

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
    @NonNull final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
        super(observer);
        mOwner = owner;
    }

    // 这里就是在 removeObserver 的时候调用的,移除和 LifecycleOwner 的关系。
    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

好像还是没有看出 LiveData 感知生命周期做了些什么事情。

不要方,我们来看下 LifecycleBoundObserver,它实现了 GenericLifecycleObserver 接口。

public interface GenericLifecycleObserver extends LifecycleObserver {
    // 当 LifecycleOwner  生命周期变化的时候会回调这个方法
    void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
}

每当 LifecycleOwner 的生命周期发生变化的时候,都会回调 onStateChanged() 方法。 我们来看下 LifecycleBoundObserver 对这个方法的实现。

@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
    // 当生命周期被销毁的时候自动移除 `Observer`
    if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
        removeObserver(mObserver);
        return;
    }
    activeStateChanged(shouldBeActive());
}

细致的你一定发现了,在 removeObserver()onStateChanged() 都调用了 activeStateChanged(),它是 ObserverWrapper 的一个方法。

private abstract class ObserverWrapper {
    final Observer<T> mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer<T> observer) {
        mObserver = observer;
    }

    abstract boolean shouldBeActive();

    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }

    void detachObserver() {
    }

    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        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);
        }
    }
}

可以看到,当 Observer 对应的 LifecycleOwner 由不活跃变成活跃状态的时候, LiveData 会主动去通知 Observer 刷新一次。

接下来,我们再来看看 dispatchingValue()

private void dispatchingValue(@Nullable ObserverWrapper initiator) {
    // ...
    
    // 生命周期从不活跃变为活跃的时候,通知指定的Observer
    if (initiator != null) {
        considerNotify(initiator);
        initiator = null;
    } else {
    // 会通知所有的 Observer
        for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
            // 主要是这个方法在做数据刷新
            considerNotify(iterator.next().getValue());
        }
    }
    
    // ...
}

我们再来看看 considerNotify()

private void considerNotify(ObserverWrapper observer) {
    // 如果 Observer 对应的 LifecycleOwner 是不活跃的,则不进行通知。
    if (!observer.mActive) {
        return;
    }
    // 不活跃的时候会将 Wrapper 置为不活跃状态
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    // 说明 Observer 已经是最新的值了
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    // 通知 Observer 刷新
    observer.mObserver.onChanged((T) mData);
}

 

最后

以上就是自觉小兔子为你收集整理的Jetpack 之 LiveData 源码分析LiveData数据容器可被观察的全部内容,希望文章能够帮你解决Jetpack 之 LiveData 源码分析LiveData数据容器可被观察所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部