【Android】深入源码理解LiveData的实现原理

1 背景介绍

1.1 LiveData是什么

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,即它遵循其他应用组件(如 Activity/Fragment)的生命周期。这种感知能力可确保 LiveData仅更新处于活跃生命周期状态的应用组件观察者。

【Android】深入源码理解LiveData的实现原理_第1张图片

1.2 LiveData特点

  • 实时数据刷新:当组件处于活跃状态或者从不活跃状态到活跃状态时总是能收到最新的数据;

  • 不会发生内存泄漏:observer会在LifecycleOwner状态变为DESTROYED后自动remove;

  • 不会因 Activity 处于STOP等状态而导致崩溃:如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件;

  • 不需要手动解除观察:开发者不需要在onPauseonDestroy方法中解除对LiveData的观察,因为LiveData能感知生命周期状态变化,所以会自动管理所有这些操作;

  • 数据始终保持最新状态:数据更新时,若LifecycleOwner为非活跃状态,那么会在变为活跃时接收最新数据。例如,曾经在后台的 Activity 会在返回前台后,observer立即接收最新的数据等;

1.3 LiveData使用介绍

基本使用

//数据层
val mData = MutableLiveData<String>()


//视图层
mData.observe(this, Observer{ mData-> nameTextView.text = newName})
mData.setValue("a")
mData.postValue("b")

1.4 几个问题

  • LiveData如何实现订阅者模式,如何处理发送事件?

自身通过注册观察者,在数据更新时进行数据变更的通知;

  • 如何做到感知生命周期的,怎么跟 LifecycleOwner 进行绑定的?

ObserverLifeCycleOwner组合成新的观察者包装类,进而实现绑定以及生命周期感知;

  • LiveData 只在 LifecycleOwneractive状态发送通知,是怎么处理的?

非活跃状态数据无法感知生命周期变化,同时在considerNotify时,如果包装后的观察者不是活跃状态也无法发送通知;

  • LiveData 会自动在 DESTROY 的状态下取消订阅,是怎么处理的?

感应到生命周期为DESTROYED时会调用removeObserver()方法取消订阅;

  • 生命周期变化后数据处理流程是怎么样的?

onStateChanged ——> activeStateChanged ——> dispatchingValue ——> considerNotify ——> onChanged

  • 为什么观察者只能与一个LifecycleOwner绑定,而不是多个?

绑定多个的话,LiveData的生命周期感知能力就乱掉了,会有很多问题;

  • LiveData的粘性事件?

之前的Observer已经订阅并更新数据,mVersionmLastVersion不再保持同步那么再新增一个Observer,他也会立即受到旧的消息通知

mLastVersion < mVersion,不会走进return的逻辑);

2 源码分析

基本原理:观察者模式,对LiveData数据添加一个或者多个观察者,实现数据的订阅与分发;

主要变量:

  • mVersion:LiveData实例的版本标记,创建LiveData以及setValue时会进行更新+1;
  • mObservers:存储Observer包装类型实例的map;
  • mData:使用LiveData保存的需要观察的数据;
  • mPendingData:保存LiveData临时数据的变量,mPendingData == NOT_SET第一次一定是返回true,之后都是返回false,然后到这个值更新完毕之前的会调用mPendingData=NOT_SET,这也是为什么多次调用 postValue()只有最后一个值才有效的原因;

UML类图
【Android】深入源码理解LiveData的实现原理_第2张图片
流程图
【Android】深入源码理解LiveData的实现原理_第3张图片

2.1 注册观察者

observe(LifecycleOwner,Observer)

主要逻辑:记录观察者LifecycleBoundObserver,并将包装后的观察者绑定LifecycleOwner的生命周期;

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
  assertMainThread("observe");
    
  // LifecycleOwner处于DESTROYED状态时忽略当前订阅请求,即忽略owner的注册
  if (owner.getLifecycle().getCurrentState() == DESTROYED) {
    return;
  }
  
  //将LifecycleOwner、Observer包装成LifecycleBoundObserver,即给observer绑定一个owner,实现observer的生命周期感知
  LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    
  //在mObservers Map中没有找到这个observer的wrapper,就添加到mObservers中,返回null;否则返回已经添加的wapper
  ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
  
  //observer已经添加,但已添加的observer前面绑定的owner不是现在传进来的owner,就会报错?
  if (existing != null && !existing.isAttachedTo(owner)) {
    throw new IllegalArgumentException("Cannot add the same observer"
                                       + " with different lifecycles");
  }
  
  //已经添加过就不再重复添加,避免重复
  if (existing != null) {
    return;
  }
  
  //让wrapper来观察owner,则owner生命周期变化时可以及时通知wrapper进行处理
  owner.getLifecycle().addObserver(wrapper);
}
public V putIfAbsent(@NonNull K key, @NonNull V v) {
    Entry<K, V> entry = get(key);
    if (entry != null) {
        return entry.mValue;
    }
    put(key, v);
    return null;
}

observeForever()

@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
    assertMainThread("observeForever");
    //认为观察者一直是活跃的,不会自动移除,因为shouldBeActive()一直返回true
    AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    
    //不能影响之前LifecycleBoundObserver的逻辑,所以observer之前被绑定过owner就会报错,可以理解为隔离两种方式的处理逻辑
    if (existing instanceof LiveData.LifecycleBoundObserver) {
        throw new IllegalArgumentException("Cannot add the same observer"
                                           + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    
    //这里直接调用,不再走生命周期回调间接调用
    wrapper.activeStateChanged(true);
}

由于没有使用LifeCycleOwner,因为无相应生命周期感知能力,会认为观察者一直处于活跃状态,需要手动移除,否则可能引起内存泄露;

2.2 事件回调

简化类图
【Android】深入源码理解LiveData的实现原理_第4张图片

LifecycleBoundObserver --> 生命周期感知的观察者包装类

实现了LifecycleEventObserver接口,相比于Observer增加了生命周期感知能力,即onStateChanged()回调,在LifecycleOwner处于DESTROYED状态时移除Observer(即LiveData自动移除观察者的特点)。

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(STARTED);
  }

    
  //Observer绑定的LifeCyclerOwner生命周期状态改变时触发
  @Override
  public void onStateChanged(@NonNull LifecycleOwner source,
                             @NonNull Lifecycle.Event event) {
    if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
      removeObserver(mObserver);
      return;
    }
      
    //如果不是DESTROYED状态,将调用父类ObserverWrapper的activeStateChanged()方法处理 这个生命周期状态变化,shouldBeActive()的值作为参数,至少是STARTED状态为true,即活跃状态为true。
    activeStateChanged(shouldBeActive());
  }

  //重写isAttachedTo()方法,比较新的owner与之前保存的owner是否一致;
  @Override
  boolean isAttachedTo(LifecycleOwner owner) {
    return mOwner == owner;
  }

  //移除Observer
  @Override
  void detachObserver() {
    //与observe()方法里的addObserver()相对应
    mOwner.getLifecycle().removeObserver(this);
  }
}

AlwaysActiveObserver

private class AlwaysActiveObserver extends ObserverWrapper {

    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }

    @Override
    boolean shouldBeActive() {
        return true;
    }
}

ObserverWrapper–>观察者基础包装类,记录观察者状态并进行相应操作;

private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;  //标识mObserver的活跃状态
    int mLastVersion = START_VERSION;

    ObserverWrapper(Observer<? super 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;
        
        //mActiveCount指的是活跃的观察者数量,等于0即没有活跃的观察者(旧状态)
        boolean wasInactive = LiveData.this.mActiveCount == 0;
        
        //根据最近传进来的状态来增加/减少观察者(更新状态)
        LiveData.this.mActiveCount += mActive ? 1 : -1;
        
        //活跃观察者数量由0->1
        if (wasInactive && mActive) {
            onActive();
        }
        
        //活跃观察者数量由1->0
        if (LiveData.this.mActiveCount == 0 && !mActive) {
            onInactive();
        }
        
        //【注:预留的方法,这两个方法作用后面再说】
        
        //观察者变为活跃,则进行数据分发(即只有活跃状态才会进行数据分发)
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

dispatchingValue()–>数据分发

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    
    //正在进行数据分发,则本次分发无效
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    
    //前后两个mDispatchingValue,保证单次数据分发过程不被打扰
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        
        //ObserverWrapper不为空,即在进行添加观察者时通知真正的观察者进行更新
        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;
}
变量 初始值 第1次 第N次 正在分发
mDispatchingValue null true->false false->false true->false
mDispatchInvalidated null false false false(正在分发)->true(新的分发,重新通知) ->false(分发完成)

considerNotify()–>执行回调

private void considerNotify(ObserverWrapper observer) {
    
    //观察者不活跃,return
    if (!observer.mActive) {
        return;
    }

    //observer绑定的owner不是活跃状态,再次调用activeStateChanged()方法并传入false进行判断
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);  //目的是执行onInActive()方法
        return;
    }
    
    //保证只有在LiveData数据更新后才可以进行onChanged()回调,避免重复分发数据
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    
    observer.mLastVersion = mVersion;
    
    //回调Observer的onChanged()方法,再去业务中进行相关操作
    observer.mObserver.onChanged((T) mData);
}

2.3 数据更新

setValue

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

setValue()把value赋值给mData,更新版本号,然后调用dispatchingValue(null),参数是null,对应前面提到的observerWrapper为空的场景,即遍历所有观察者进行分发回调。

postValue

mPendingData上的生产与赋值需要加锁,这是为了保证mPendingData的线程安全;

protected void postValue(T value) {
    //定义一个 postTask 的布尔值,判断是否要更新
    boolean postTask;
    
    //加个同步锁,因为可能存在多个子线程同时调用 .postValue() 的情况
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value; //连续postValue会更新全局的临时数据mPendingData
    }
    
    //避免同时多次postValue的执行影响性能,UI只需要显示最终状态即可;
    if (!postTask) {
        return;
    }
    //将Runnable对象往主线程里执行
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            //数据更新之前,恢复mPendingData的初始状态
            mPendingData = NOT_SET;
        }
        
        //主线程调用
        setValue((T) newValue);
    }
};

注意

  • 如果同时调用 postValue(“a”)和setValue(“b”),一定是值b被值a覆盖 => 原因:b直接分发数据,但是a还需要等到子线程执行setVlaue()方法;
  • 如果多次连续调用 postValue(),需要先执行完多个postValue()方法来更新数据mPendingData,最后在主线程setValue时是使用最后一次设置的数据,因此只有最后一个值能够被分发;

2.4 移除观察者

removeObserver()

@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    assertMainThread("removeObserver");
    //从mObservers取出需要移除的wrapper
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        return;
    }
    
    //解除observer与owner的绑定关系
    removed.detachObserver();
    
    //再次调用activeStateChanged()方法,更新observer的状态
    removed.activeStateChanged(false);
}

removeObservers()

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

3 流程总结

3.1 注册观察者流程

observe(生命周期感知)——> onStateChanged——> activeStateChanged ——> dispatchingValue(observerWrapper) ——> considerNotify ——> onChanged

3.2 更新数据流程

setValue ——> dispatchingValue(null)——> considerNotify ——> onChanged

【Android】深入源码理解LiveData的实现原理_第5张图片

4 特殊用法

4.1 利用单例模式实现应用全局数据共享

public class StockLiveData extends LiveData<BigDecimal> {
    private static StockLiveData sInstance; //单实例
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);//监听到股价变化 使用setValue(price) 告知所有活跃观察者
        }
    };

    //获取单例
    @MainThread
    public static StockLiveData get(String symbol) {
        if (sInstance == null) {
            sInstance = new StockLiveData(symbol);
        }
        return sInstance;
    }

    private StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    //活跃的观察者(LifecycleOwner)数量从 0 变为 1 时调用
    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);//开始观察股价更新
    }

    //活跃的观察者(LifecycleOwner)数量从 1 变为 0 时调用。这不代表没有观察者了,可能是全都不活跃了。可以使用hasObservers()检查是否有观察者。
    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);//移除股价更新的观察
    }
}

4.2 其它用法

在将 LiveData 对象分派给观察者之前对存储在其中的值进行更改,或者需要根据另一个实例的值返回不同的 LiveData实例,可以使用LiveData中提供的Transformations类。

4.2.1 数据修改

MutableLiveData<Integer> liveData1 = new MutableLiveData<>();

//修改LiveData数据
LiveData<String> liveDataMap = Transformations.map(liveData1, new Function<Integer, String>() {
    @Override
    public String apply(Integer input) {
        String s = input + "-change";
        return s;
    }
});

//给liveDataMap添加观察者
liveDataMap.observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.i(TAG, "onChanged: "+s);  //onChanged: 100-change
    }
});

liveData1.setValue(100);

源码

@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) {
            result.setValue(mapFunction.apply(x));
        }
    });
    return result;
}

4.2.2 数据切换

相当于添加一个开关来控制使用哪个数据源

//两个liveData,由liveDataSwitch决定 返回哪个livaData数据
MutableLiveData<String> liveData3 = new MutableLiveData<>();
MutableLiveData<String> liveData4 = new MutableLiveData<>();

//切换条件LiveData,liveDataSwitch的value 是切换条件
MutableLiveData<Boolean> liveDataSwitch = new MutableLiveData<>();

//liveDataSwitchMap由switchMap()方法生成,用于添加观察者
LiveData<String> liveDataSwitchMap = Transformations.switchMap(liveDataSwitch, new Function<Boolean, LiveData<String>>() {
    @Override
    public LiveData<String> apply(Boolean input) {
        //这里是具体切换逻辑:根据liveDataSwitch的value返回哪个liveData
        if (input) {
            return liveData3;
        }
        return liveData4;
    }
});

liveDataSwitchMap.observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.i(TAG, "onChanged2: " + s);
    }
});

boolean switchValue = true;
liveDataSwitch.setValue(switchValue);//设置切换条件值

liveData3.setValue("liveData3");
liveData4.setValue("liveData4");

4.2.3 观察多个数据-MediatorLiveData

MediatorLiveDataLiveData 的子类,继承自MutableLiveData,允许合并多个 LiveData 源,只要任何原始的 LiveData 源对象发生更改,就会触发 MediatorLiveData 对象的观察者。

MediatorLiveData<String> mediatorLiveData = new MediatorLiveData<>();

MutableLiveData<String> liveData5 = new MutableLiveData<>();
MutableLiveData<String> liveData6 = new MutableLiveData<>();

//添加 源 LiveData
mediatorLiveData.addSource(liveData5, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.i(TAG, "onChanged3: " + s);
        mediatorLiveData.setValue(s);
    }
});
//添加 源 LiveData
mediatorLiveData.addSource(liveData6, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.i(TAG, "onChanged4: " + s);
        mediatorLiveData.setValue(s);
    }
});

//添加观察
mediatorLiveData.observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.i(TAG, "onChanged5: "+s);
        //无论liveData5、liveData6更新,都可以接收到
    }
});

liveData5.setValue("liveData5");
//liveData6.setValue("liveData6");

5 LiveData实现事件总线

LiveEventBus

public class LiveEventBus {

    public static <T> MutableLiveData<T> getDefault(String key, Class<T> clz) {
        return ready().with(key, clz);
    }

    private final Map<String, MutableLiveData<Object>> bus;

    private static LiveEventBus get() {
        return LiveEventBus.InstanceHolder.INSTANCE;
    }
    
    private static class InstanceHolder {
        static final LiveEventBus INSTANCE = new LiveEventBus();
    }
    
    private LiveEventBus() {
        bus = new HashMap<>();
    }
    
    @SuppressWarnings("unchecked")
    private <T> MutableLiveData<T> with(String key, Class<T> clz) {
        if (!bus.containsKey(key)) {
            MutableLiveData<Object> liveData = new MutableLiveData<>();
            bus.put(key, liveData);
        }
        return (MutableLiveData<T>) bus.get(key);
    }
}

用法

//发送数据
LiveEventBus.with("Event1",String.class).setValue("推送数据1"); //或者
LiveEventBus.with("Event1",String.class).postValue("推送数据1");

//监听数据
LiveEventBus.with("Event1",String.class).observe(this, new Observer<String>() {
            @Override
            public void onChanged(final String event) {
                //Todo
            }
        });

本质就是将LiveData定义为一个单例,再进行数据通信;

参考文章

https://juejin.cn/post/6903143273737814029#heading-5
https://juejin.cn/post/6844904082369413133#heading-18

你可能感兴趣的:(Android,android)