Android Architecture Component Source resolve the LiveData

table of Contents

Source parsing directory

Foreword

The big question is the Android application development framework missing, at least I have observed is this. I think the blame can not say that this is a problem the programmer level, Android itself also has its problems. Android was born more than a decade, but the Android platform does not provide a simple-to-use program for us to address such a fundamental issue which put the code. So, the result is that it does not know what to put inside the four component stack it, heap too much, then write a Util class it, nothing more.
Google also estimated discovered the problem, the official launch of architecture in 2017, AAC. Although a bit late, but the effect is very significant, so all of a sudden from Yuanshishehui Android application development slash and burn, directly to modern society. Have to say, Google a shot, you know there is not. Google I / O on the 2019 data released say, Top 1000 applications on Google Play, 80% used AAC architecture. Enough to see the popularity of the AAC.

problem

How is the data transmission is the key to any architecture, and data transmission is to rely on AAC architecture LiveData. LiveData can be described as data transmission scheme tailor-made for Android, which not only solved the problem of how data transmission, but also solve the problem of the complexity of the life cycle of the Android platform. LiveData "magic" thing is that it is perceived life cycle, after onStart observer will be notified, onDestroy when the observer will be removed automatically, avoiding null pointers and memory leaks to the maximum extent. This is what we are looking for answers in LiveData source code, all of this is how to achieve. (Source Version androidx.lifecycle: lifecycle-extensions: 2.2.0-alpha01)

1. LiveData duties

LiveData What responsibilities should complete it? No outside these points:

  1. Add the observer contains LifecycleOwner
  2. When ON_DESTROY event LifecycleOwner, removing observer
  3. LiveData data after the change, and whether to notify the viewer (or observer may not be in STARTED RESUMED state)
  4. When the state changes the life cycle, whether to notify observers (this time may come STARTED life cycle or RESUMED state, and before that a backlog of data without notice)
  5. Notification observers, and to avoid duplication of notification

The main source of content LiveData is to deal with these issues.

2. LiveData add observer

Add to LiveData with LifecycleOwner observer is particularly simple, call its observemethods to:

public abstract class LiveData<T> {
    /**
     * LiveData的观察者集合,以键值对的形式被添加进去,
     * 原始观察者Observer是键,对Observer的包装类ObserverWrapper是值。
     * SafeIterableMap是支持库内部实现的一种数据结构,底部以链表实现,表面上看上去却像个Map
     */
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();
            
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //如果Lifecycle已经处于DESTROYED状态,直接返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //对我们提供的observer进行包装,看包装类的名字 LifecycleBoundObserver 就知道,
        // 要包装成一个跟生命周期关联的观察者类
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        
        //mObservers是LiveData观察者的集合
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //不允许相同的owner,observer组合重复添加
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        //我们的包装类LifecycleBoundObserver还是LifecycleEventObserver
        //它也被添加到了Lifecycle的观察者中
        owner.getLifecycle().addObserver(wrapper);
    }
}

//LiveData观察者的定义
public interface Observer<T> {
    void onChanged(T t);
}

Code is small, a lot of things involved. We provide observers observer, after being packaged both been added to the set of observers LiveData's, it has been added to the collection in the Lifecycle of an observer. This ensures that at least two things: first, after the data changes LiveData, observer be notified; the second, when the change lifecycle status, observer can be notified. That LiveData responsibilities third, fourth two points.
LiveData itself defines the observer Observeris very simple, only one onChangedmethod is called when LiveData data changes. However, as mentioned earlier, LiveData biggest feature is that it is closely associated with the life cycle. Its observemethod contains two parameters, LifecycleOwnerand Observereach Observeralso comes with the owner of a life cycle LifecycleOwner. In order to complete said earlier duties and responsibilities 4 3, the need for Observerpackaging, which increases the more that state, so only ObserverWrapper, LifecycleBoundObserver.

public abstract class LiveData<T> {
    static final int START_VERSION = -1;
    
    //有多少LiveData的观察者处于“活动”状态
    int mActiveCount = 0;
    
    private abstract class ObserverWrapper {
        //被包装者,即LiveData原始的观察者
        final Observer<? super T> mObserver;
        //观察者是否处于“活动”状态;为原始观察者mObserver增加属性,这也是包装类的意义
        boolean mActive;
        //每个ObserverWrapper初始时version都被设置为了START_VERSION
        int mLastVersion = START_VERSION;

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

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

        /**
         * ObserverWrapper的主要职责就是:接收来自外部的activeState状态的变化,
         * 这里的activeState指的是被包装者 mObserver 是否处于“活动”状态
         * 处于“活动”状态的观察者可以接收LiveData数据的变化,否则则不能;
         * 以上所说的活动状态指的是当前观察者的活动状态,可以理解为 mObserver 的活动状态,
         * LiveData本身也有活动状态,当LiveData从“活动”状态变为“非活动”状态时,其onActive方法会被调用;
         * 当LiveData从“非活动”状态变为“活动”状态时,其onInactive方法会被调用;
         * LiveData的活动状态取决于它本身的观察者是否至少有一个处于“活动”状态
         */
        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            //为LiveData处于活动的观察者计数
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
                onActive(); //LiveData中的方法,空实现
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive(); //LiveData中的方法,空实现
            }
            if (mActive) {
                //LiveData中的方法,每当观察者来的“活动”状态时,就会分发LiveData中的数据,
                //至于observer中的onChanged方法会不会被调用,还有别的判断,之后再看
                dispatchingValue(this);
            }
        }
    }
}

ObserverWrapper primary responsibility is to change the active state of the processing, this active state comprises an active state observer, and LiveData active state (note distinguish between the two).

Herein, the active state refers to a state, there are two cases, "active" and "inactive"; "active" state refers to a state in which the "active" case

Note that activeStateChangedthe method is invoked on the outside, that is, where there is a change of status monitor, and is responsible for notifying ObserverWrapper, then we will see.

Let's look further for ObserverWrapper packaging LifecycleBoundObserver:

public abstract class LiveData<T> {

    /**
     * 很重要的一点LifecycleBoundObserver实现了LifecycleEventObserver接口,
     * 这个接口是对于生命周期事件的观察者,详见Lifcycle源码解析
     */
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

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

        //生命周期至少处于STARTED状态时,观察者才是“活动”状态
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        //该方法是接口LifecycleEventObserver中的方法
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            //生命周期来到了DESTROYED,则从LiveData中移除原始的观察者mObserver
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                //指的是LiveData中的removeObserver方法
                //removeObserver方法会把观察者从LiveData的观察者集合中移除,
                //然后还会调用下面的detachObserver方法,从Lifecycle中移除观察者
                removeObserver(mObserver);
                return;
            }
            //上面提到的ObserverWrapper中的activeStateChanged方法,
            //每当生命周期变化时就调用activeStateChanged
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        //从生命周期观察者中移除
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
}

After reviewing the procedures once add an observer for LiveData, our observers Observerare packaged become LifecycleBoundObserver, then they are added to the set of observers LiveData in, and observers in Lifecycle. LifecycleBoundObserverBehind package is actually two, the first layer is a package ObserverWrapper(LiveData can be added to the observer), the second layer is a package LifecycleBoundObserver(achieved LifecycleEventObserver, it can be added to the observer in Lifecycle).

4803763-58eff5e323795537.png

Then look at LifecycleBoundObserverthe source code, comments have been written very clearly, when mainly on two points:

  1. When the change lifecycle status notification activity is in the "active" in (in an "active" state observer, and when there before "backlog" of data not notice, the observer onChangedmethod is called)
  2. Life cycle came to DESTROYED, remove the corresponding observer (from LiveData and Lifecycle)

To summarize, LiveData add content viewer:

  1. Observer for packaging
  2. The Observer Packaged separately added to the observer LiveData and Lifecycle
  3. Convert life cycle changes as a change in the active state, and notifies the viewer (ObserverWrapper) activity state changes
  4. Life cycle came to DESTROYED, remove the corresponding observer (from LiveData and Lifecycle)

2,4 bar LiveData duties have been verified. The following is how to inform the main view of the observer LiveData data changes, and how to avoid duplicate notifications. That is, the third duty LiveData, fifth two.

3. LiveData notification data

LiveData need to distribute data in two situations:

  1. LiveData itself when data changes
  2. When an observer due to changes in the life cycle becomes "active"

The reason why speak distributed data rather than the data change notification, because real change notification data also depends on other factors, for example, the viewer is in "active" state, whether the viewer has already received this data.

LiveData need to change their data setValueor postValuemethods, depending on whether the main thread to modify data:

public abstract class LiveData<T> {
    //数据锁
    final Object mDataLock = new Object();
    static final int START_VERSION = -1;
    //初始时下LiveData处于未设置状态
    static final Object NOT_SET = new Object();

    //LiveData真正的Data,LiveData的数据
    private volatile Object mData;
    //通过postValue设置数据
    volatile Object mPendingData = NOT_SET;
    //LiveData的数据version,用于与观察者的version进行比较,避免重复通知
    private int mVersion;

    private boolean mDispatchingValue;
    private boolean mDispatchInvalidated;
    
    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

    /**
     * 使用给定value对LiveData初始化
     */
    public LiveData(T value) {
        mData = value;
        mVersion = START_VERSION + 1;
    }

    /**
     * 默认初始化
     */
    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }
    
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        //切换到主线程去设置数据,ArchTaskExecutor是AAC中使用的线程池,Room也在使用
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
    
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        //version增加
        mVersion++;
        mData = value;
        //分发数据的变化
        dispatchingValue(null);
    }
}

It can be seen postValuemethod eventually calls the setValuemethod, setValuethe method is simple, increase the version number, setting data, and distribute data.
We look to follow up dispatchingValuemethod:

public abstract class LiveData<T> {
    //initiator如果为null,证明是LiveData的数据发生了变化,要对所有观察者分发数据,
    //如果initiator不为null,那说明是因为这个initiator代表的观察者变为“活动”状态,只需要通知这个initiator本身就可以了
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //mDispatchingValue和mDispatchInvalidated两个标志是为了防止在数据分发的时候,LiveData的数据再次发生变化;
        //例如,某个观察者onChanged方法内部又调用了setValue方法
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator); //只通知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;
    }
    
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) { //非“活动”状态的observer不通知数据的变化
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        // 这个判断我没有看懂,包括上面的注解本身我也没有看懂,留作一个疑问,有明白的还望告知
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //观察者的version不小于LiveData的version,说明该观察者已经被通知过了,不再通知
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //终于看到了我们observer的onChanged方法被调用
        observer.mObserver.onChanged((T) mData);
    }
}

LiveData context of data distribution is still very clear, because LiveData data changes, the notification to all observers consider whether changes in the data; as a viewer becomes "active" only itself to consider whether to notify the observer changes in the data. And by comparing LiveData and the observer (ObserverWrapper) version number to avoid duplicate notifications. LiveData duty third and two 5 has also been verified.


Here, the source is substantially on LiveData analysis finished, some elements omitted as follows:

  1. LiveData removed observer
  2. Add to LiveData "permanent" observers ( observeForevermethods), said to be "permanent" observers, in fact, is not bound observer of the life cycle, can also be manually removed.
  3. MutableLiveData

The content is relatively simple, in this skip.

4. LiveData conversion Transformations

Mentioned above, the LiveData of onActiveand onInactivemethods, respectively, in LiveData becomes "active" and become to be called when the "inactive", but in the realization of LiveData itself in, onActiveand onInactiveare empty implementation. In fact, for a single observation of changes LiveData data is concerned, does not need to implement change LiveData itself active, these two methods are mainly used to customize LiveData LiveData or to be converted. Specific usage scenarios see Google Docs . The following detailed analysis about LiveData conversion.

The simplest example is the conversion of LiveData map, like the map as RxJava. The key is to achieve the conversion LiveData MediatorLiveData categories:

//类如其名,中介者LiveData
public class MediatorLiveData<T> extends MutableLiveData<T> {
    private SafeIterableMap<LiveData<?>, Source<?>> mSources = new SafeIterableMap<>();

    /**
     * 添加作为“源”的LiveData,和对“源”的LiveData的观察者
     * 当“源”LiveData数据变化,并且当前MediatorLiveData处于“活动”状态(拥有“活动”观察者)时,onChanged就会被调用
     * 实际上正如类名一样,这实际上起到了中介者的作用,MediatorLiveData传递了“源”LiveData的数据变化,同时我们又可以在onChanged中对“源”LiveData的数据进行转换
     */
    @MainThread
    public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
        Source<S> e = new Source<>(source, onChanged);
        Source<?> existing = mSources.putIfAbsent(source, e);
        if (existing != null && existing.mObserver != onChanged) {
            throw new IllegalArgumentException(
                    "This source was already added with the different observer");
        }
        if (existing != null) {
            return;
        }
        if (hasActiveObservers()) {
            e.plug();
        }
    }

    /**
     * 移除“源”LiveData
     */
    @MainThread
    public <S> void removeSource(@NonNull LiveData<S> toRemote) {
        Source<?> source = mSources.remove(toRemote);
        if (source != null) {
            source.unplug();
        }
    }

    @CallSuper
    @Override
    protected void onActive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().plug();
        }
    }

    @CallSuper
    @Override
    protected void onInactive() {
        for (Map.Entry<LiveData<?>, Source<?>> source : mSources) {
            source.getValue().unplug();
        }
    }

    private static class Source<V> implements Observer<V> {
        final LiveData<V> mLiveData;
        final Observer<? super V> mObserver;
        int mVersion = START_VERSION;

        Source(LiveData<V> liveData, final Observer<? super V> observer) {
            mLiveData = liveData;
            mObserver = observer;
        }

        void plug() {
            mLiveData.observeForever(this);
        }

        void unplug() {
            mLiveData.removeObserver(this);
        }

        @Override
        public void onChanged(@Nullable V v) {
            if (mVersion != mLiveData.getVersion()) {
                mVersion = mLiveData.getVersion();
                mObserver.onChanged(v);
            }
        }
    }
}

Just look MediatorLiveData may be more ignorant force, all right, combined map etc. Convert watching to understand what it means.

@SuppressWarnings("WeakerAccess")
public class Transformations {

    private Transformations() {
    }

    /**
     * 最简单明了的转换操作
     * 传入source “源”LiveData,将其转换为另一种类型的LiveData
     * LiveData<X> -> LiveData<Y>
     */
    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> map(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, Y> mapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            @Override
            public void onChanged(@Nullable X x) {
                //source的变化会通知到这个方法,我们用mapFunction对我们接收到的数据进行转换
                result.setValue(mapFunction.apply(x));
            }
        });
        //返回中介 MediatorLiveData
        return result;
    }

    /**
     * 这个方法比较不好理解,可以去看源码中的注释帮助理解
     */
    @MainThread
    @NonNull
    public static <X, Y> LiveData<Y> switchMap(
            @NonNull LiveData<X> source,
            @NonNull final Function<X, LiveData<Y>> switchMapFunction) {
        final MediatorLiveData<Y> result = new MediatorLiveData<>();
        result.addSource(source, new Observer<X>() {
            LiveData<Y> mSource;

            @Override
            public void onChanged(@Nullable X x) {
                LiveData<Y> newLiveData = switchMapFunction.apply(x);
                if (mSource == newLiveData) {
                    return;
                }
                if (mSource != null) {
                    result.removeSource(mSource);
                }
                mSource = newLiveData;
                if (mSource != null) {
                    result.addSource(mSource, new Observer<Y>() {
                        @Override
                        public void onChanged(@Nullable Y y) {
                            result.setValue(y);
                        }
                    });
                }
            }
        });
        return result;
    }

    /**
     * 直到source数据跟上次的数据不同时才通知
     */
    @MainThread
    @NonNull
    public static <X> LiveData<X> distinctUntilChanged(@NonNull LiveData<X> source) {
        final MediatorLiveData<X> outputLiveData = new MediatorLiveData<>();
        outputLiveData.addSource(source, new Observer<X>() {

            boolean mFirstTime = true;

            @Override
            public void onChanged(X currentValue) {
                final X previousValue = outputLiveData.getValue();
                if (mFirstTime
                        || (previousValue == null && currentValue != null)
                        || (previousValue != null && !previousValue.equals(currentValue))) {
                    mFirstTime = false;
                    outputLiveData.setValue(currentValue);
                }
            }
        });
        return outputLiveData;
    }
}

The original Transformations like this map only one way, now added two, the source code is not difficult to understand, the core idea is to get the "source" LiveData data, after the data and then do the conversion, and then set to MediatorLiveData, so by MediatorLiveData, the conversion is complete.
As can be seen, LiveData want to imitate RxJava as operator, but design with RxJava LiveData difference is still very large, it enables operators is very limited. Transformations main role is passed correctly "source" data changes LiveData, and to ensure the observer's life cycle can be passed to the "source" LiveData. To put it plainly, it is to let MediatorLiveData no sense of presence.

5. Hidden Skills

  1. If our observer in "inactive" status, he becomes "active" only receive the latest data, that data is LiveData will 'collapse' of.
  2. Unless you to artificially LiveData data set is null ( setValue(null)or postValue(null)), or received in Observer onChanged method of the null data is not possible. If you use some third-party libraries LiveData provided, in the judgment onChanged space it is necessary, maybe it is a null any special meaning representative.

6. Summary

Our observer after packaging, be added to the set of observers LiveData, meanwhile, has also been added to the Lifecycle observers we provide the collection (if we provide LifecycleOwner words), so that both the data itself occurs LiveData when changes or observer becomes "active" state, it will be our cue to observers. But only when our observer in an "active" state and had not been notified (version lower than LiveData's version), onChanged method will be called the Observer.

Guess you like

Origin blog.csdn.net/weixin_34137799/article/details/90789082