MVVM communication of Jetpack - principle analysis of LiveData

Posted by splatek on Mon, 06 Sep 2021 20:55:39 +0200


In the last article, we introduced the basic use and principle analysis of ViewModel. Because ViewModel usually needs to be used in combination with inter component communication tools, the last article also talked about the scenario of the combination of ViewModel and LiveData. This time, we will analyze some principles of LiveData combined with the examples in the previous article.

Previous: MVVM implementation of Jetpack - use and source code analysis of ViewModel__ biz=Mzk0ODAyNjE3Nw==&mid=2247484048&idx=1&sn=50f8983b475deadb677efe4deee37cd2&chksm=c36cacbef41b25a8bdbde0999410d85dfa05ac07b19247adf4640c294f4e78615f01393763c9&token=2095993980&lang=zh_ CN#r

1. Use

Because this time we will mainly analyze some principles of LiveData, we will not create a Demo. To facilitate analysis, paste the last part of the code:

        // Note 1, registered observer
        mLiveData.observe(this, new Observer<String>() {
            public void onChanged(String s) {
                Toast.makeText(getApplicationContext(), "mag = " + s, Toast.LENGTH_SHORT).show();
       // Note 2, transmit data

2. Source code analysis

Now let's start with notes 1 and 2 above to analyze the registration and data transmission process of LiveData.

  • To register, first look at the registration process of the observer. The observe method in note 1 above:
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // Note 3, get the Activity life cycle
            // If the component is in the DESTROYED state, registration is not allowed
        LiveData.LifecycleBoundObserver wrapper = new LiveData.LifecycleBoundObserver(owner, observer);
        // Note 4: package the component and observer and store them in the linked list. If the object already exists, it will not be overwritten and existing will not be empty
        LiveData.ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        // Note 5: if the observer already exists, return and do not repeat the registration
        if (existing != null) {
        // Note 6, save the observer in Lifecycle to complete the registration
    //Note 7, putIfAbsent method
    public V putIfAbsent(@NonNull K key, @NonNull V v) {
        SafeIterableMap.Entry<K, V> entry = get(key);
        if (entry != null) {
            return entry.mValue;
        put(key, v);
        return null;

In note 3 above, we can see that LiveData judges the state of the observer component life cycle before registering the observer. If the observer lifecycle is already in   If the status is DESTROYED, it will be returned directly and will not be registered. Then, at the place of note 4, the wrapped observer object will be saved into the Map in the form of key value pairs.

If the object already exists, the overwrite operation is not performed, and the existing returned is not null. At this time, the registration method returns directly, and the registration will not be repeated. See note 7 for putIfAbsent storage method logic.

If the packaged observer object has not been saved and registered before, complete the registration in the Lifecycle of note 6 above. Now look at the observer wrapper class LifecycleBoundObserver in LiveData at note 4 above:

    class LifecycleBoundObserver extends LiveData.ObserverWrapper implements LifecycleEventObserver {
        final LifecycleOwner mOwner;
        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            mOwner = owner;
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        public void onStateChanged(@NonNull LifecycleOwner source,
                                   @NonNull Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                // Note 8, when the component life cycle changes, the method is called back
                // When the component lifecycle state is DESTROYED, the observer is removed
                // In this way, no data will be received when the observer component is in the destroyed state
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        void detachObserver() {
    // Remove observer
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        LiveData.ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {

The onStateChanged method in note 8 above calls back when the component life cycle changes. After judgment, the observer will be removed when the component lifecycle state is DESTROYED. In this way, no data will be received when the observer component is in the DESTROYED state.

According to the above analysis of the registration process, we briefly summarize the following two points for the LiveData life cycle:

(1) LiveData is not registered when the observer is destroyed

(2) LiveData has the life cycle awareness of components (through LifeCycle). When the component is destroyed, LiveData removes the observer to avoid memory leakage.

  • Next, go back to note 2 above and start with the LiveData.postValue(result) method to see the LiveData data data sending process:
    public void postValue(T value) {
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        if (!postTask) {
        // Note 9: package the message to be sent and switch to the main thread to execute the setValue () method
    private final Runnable mPostValueRunnable = new Runnable() {
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            // Note 10, the setValue () method is executed in the main thread
            setValue((T) newValue);

From the comments above, we can see that the postValue method finally switches to the main thread and executes the setValue method. Now let's look at the setValue method:

    protected void setValue(T value) {
        mData = value;
    void dispatchingValue(@Nullable LiveData.ObserverWrapper initiator) {
        for (Iterator<Map.Entry<Observer<? super T>, LiveData.ObserverWrapper>> iterator =
             mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
            //Note 11, traversing the observer
            if (mDispatchInvalidated) {
    private void considerNotify(LiveData.ObserverWrapper observer) {
        // Note 12: the observer life cycle is not Active and is not sent
        // The Active state includes STARTED and RESUMED, that is, onStart() and onResume() methods corresponding to our component life cycle
        if (!observer.mActive) {
        observer.mObserver.onChanged((T) mData);

As we can see above, setValue will call the dispatchingValue(null) method to distribute events.

The dispatchingValue method will traverse all observers and then execute the considerNotify method. So will LiveData send data to all observers? See note 12 above. Before sending data, LiveData will judge the current life cycle state of the observer.

Only observers who are currently active will receive data, and   Active   States include STARTED and RESUMED, that is, onStart() and onResume() methods corresponding to our component life cycle.

This is the conclusion we need to know. The data of LiveData will be received only when the component lifecycle is in the Start or Resume state. In this way, the component does not need to judge its current state when receiving data display.

MVVM communication of Jetpack - principle analysis of LiveData? biz=Mzk0ODAyNjE3Nw==&mid=2247484095&idx=1&sn=93aa5f589e64868a529a3b7c3631d7bb&chksm=c36cac91f41b258742f77da614f6a3e401ce997b3aa02f093a0287b5aa050cff698a7da1c7bb&token=2095993980&lang=zh_ CN#rd

Topics: architecture LiveData