LiveData 入门到手写

514 阅读4分钟

如果文章有问题,请及时指出

LiveData是android的Jetpack中重要部分,是具有生命周期感知的观察者模式。

下面我们来根据源码分析LiveData的原理。

一  LiveData入口

注册观察者

LiveData.java

// key为LiveData的观察者  value 为LiveData的观察者和生命周期绑定对象(LifecycleBoundObserver)
private SafeIterableMap, ObserverWrapper> mObservers =
        new SafeIterableMap<>();

// 注册观察者
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
    assertMainThread("observe");
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    // 这里会把生命周期和观察者进行绑定 
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);     // 把观察者存有map中
    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;
    }
    // 注册生命周期观察者,注册时会根据生命周期状态,回调生命周期观察者的change方法
    owner.getLifecycle().addObserver(wrapper);
}
生命周期回调:如果注册时生命周期已经经过多次变化,会把以前的生命周期变化事件都回调一遍。所以可能LifecycleBoundObserver.onStateChanged会在注册时调用多次(比如在onResume之后再注册LiveData观察者)。

看下LifecycleBoundObserver,这个类包装了生命周期观察者和我们注册的liveData观察者。

LiveData.java

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

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

    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    // 生命周期变化,会调用此方法
    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        // 调用ObserverWrapper中方法
        activeStateChanged(shouldBeActive());
    }

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

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

LifecycleBoundObserver的父类ObserverWrapper,其中包含:liveData观察者的版本和当前观察者是否活跃等信息。

private abstract class ObserverWrapper {
    final Observer mObserver;
    boolean mActive; // mActive是否活跃
    int mLastVersion = START_VERSION; // 上一个版本

    ObserverWrapper(Observer observer) {
        mObserver = observer;
    }

    abstract boolean shouldBeActive();

    boolean isAttachedTo(LifecycleOwner owner) {
        return false;
    }

    void detachObserver() {
    }

    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();
        }
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            onInactive();
        }
        // 会调用liveData数据变化
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

由上面的可知,在生命周期变化时,会调用LiveData观察者的onChange方法。在观察者注册前上一个消息也会传给观察者。

二 传输数据

异步传输:LiveData.postValue

同步传输:LiveData.setValue

这里就分析setValue,因为postValue就是利用handler处理的。

@MainThread 
protected void setValue(T value) { 
   assertMainThread("setValue"); 
   // 更新LiveData的版本号
   mVersion++;  
   mData = value;
   // 调用数据传递方法
   dispatchingValue(null);
}

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            // 生命周期变化走此处
            considerNotify(initiator);
            initiator = null;
        } else {
            // 从map中取出所有观察者,分别调用considerNotify
            for (Iterator, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                // setValue走此处
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

private void considerNotify(ObserverWrapper observer) {
    // 观察者非活跃不做处理。STARTED和RESUMED状态才能传递消息
    if (!observer.mActive) {
        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.
    // 这里会判断当前生命周期owner的状态是不是在STARTED之后。(会出现这种情况吗???)
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    // 版本控制
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    // 更新观察者的版本号
    observer.mLastVersion = mVersion;
    //noinspection unchecked
    observer.mObserver.onChanged((T) mData);
}

总结:LiveData的观察者能感知生命周期,是因为它内部注册的生命周期观察者,只有在STARTED和RESUMED状态才传递数据。

Observe.onChanged()回调时机: (有版本、是否活跃、LifecycleOwner状态判断)

  1. 注册Observer时,根据生命周期状态可能回调。
  2. 生命周期发送变化时,可能回调。
  3. LiveData.setValue() LiveData.postValue()可能会回调。
粘性事件处理:(**重写方案不好**,父类执行observe时可能回调Observe.onChanged(),消息已经传递了)
如果观察者不想接受之前的消息,可以在注册是把观察者的版本号改成和liveData一样。需要重写LiveData 的public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) ;反射实现观察者和LiveData中版本一样。

三 手写LiveData

package com.example.mylivedata;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;

import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.STARTED;

/**
 * 简化的LiveData 
 * @author 陆小凤
 * @date 20/7/31
 */
public class SimplifiedLiveData {
    /** 初始化版本信息 */
    public static final int INIT_VERSION = -1;
    /** 数据 */
    private T mData;
    /** 观察者集合 */
    private List mObservers = new ArrayList<>();
    /** 版本信息 */
    private int mVersion = INIT_VERSION;

    /**
     * 修改数据
     *
     * @param data 数据
     */
    @MainThread
    public void setValue(T data) {
        mData = data;
        mVersion++;
        dispatchValue();
    }

    /**
     * 传递数据变化
     */
    private void dispatchValue() {
        for (ObserverWrap wrap : mObservers) {
            considerNotify(wrap);
        }
    }

    /**
     * 确认通知数据变化
     *
     * @param wrap 观察组合对象
     */
    private void considerNotify(ObserverWrap wrap) {
        // 生命周期状态不为RESUMED和STARTED,则不处理
        if (!wrap.mLifeOwner.getLifecycle().getCurrentState().isAtLeast(STARTED)) {
            return;
        }
        // 判断版本信息
        if (wrap.mLastVersion >= mVersion) {
            return;
        }
        wrap.mLastVersion = mVersion;
        wrap.mObserver.onChanged(mData);
    }

    /**
     * 注册观察
     *
     * @param lifecycleOwner 生命周期Owner对象
     * @param observer       观察者
     * @param isSticky       是否是粘性 true:粘性;false:非粘性(注册行为以前的数据变化不处理)
     */
    @MainThread
    public void observe(@NonNull LifecycleOwner lifecycleOwner, @NonNull Observer observer, boolean isSticky) {
        if (lifecycleOwner.getLifecycle().getCurrentState() == DESTROYED) {
            return;
        }
        if (isContainObserver(observer)) {
            return;
        }
        ObserverWrap wrap = new ObserverWrap();
        wrap.mObserver = observer;
        wrap.mLifeOwner = lifecycleOwner;
        if (!isSticky) {
            wrap.mLastVersion = mVersion;
        }
        mObservers.add(wrap);
        lifecycleOwner.getLifecycle().addObserver(wrap);
    }

    /**
     * 判断观察者是否存在(建议使用map存观察者)
     *
     * @param observer 观察者
     * @return true:存在;false:不存在
     */
    private boolean isContainObserver(Observer observer) {
        boolean contain = false;
        for (ObserverWrap wrap : mObservers) {
            if (wrap.mObserver == observer) {
                contain = true;
                break;
            }
        }
        return contain;
    }

    /**
     * 解注册观察者
     *
     * @param observer
     */
    private void removeObserver(Observer observer) {
        mObservers.remove(observer);
    }

    /**
     * 参考Live中LifecycleBoundObserver
     * 简化:包含LifecycleOwner对象、观察者对象、版本号
     */
    class ObserverWrap implements LifecycleEventObserver {
        private LifecycleOwner mLifeOwner;
        private Observer mObserver;
        private int mLastVersion = INIT_VERSION;

        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            if (mLifeOwner.getLifecycle().getCurrentState() == DESTROYED) {
                // 解注册LiveData观察者
                removeObserver(mObserver);
                // 解注册生命周期观察者
                mLifeOwner.getLifecycle().addObserver(this);
                return;
            }
            // 当前不是DESTROYED状态的事件都传递
            dispatchValue();
        }
    }
}