![](https://img.haomeiwen.com/i5710545/ab21280711aefad3.jpg)
序言
我们知道Livedata可以监听生命周期发送数据,并且采用的是观察者模式,看源码前先思考几个问题
- 怎么观察生命周期状态?
- 为什么可发送粘性事件?
- 当重新可见的时候会不会重新接收到数据?怎么做到的?
- 触发多个生命周期方法,观察者会不会多次收到信息?怎么控制这块的?
- 怎么多个Activity共用同一个Livedata?
- AActivity发送消息,BActivity注册能收到数据吗?
- AActivity注册在BActivity#Oncreat()发送,Activity 会收到消息么?
- AActivity注册在BActivity#点击事件发送,Activity 会收到消息么
按照创建->添加观察者->发送数据流程对Livedata分析
1.创建做了什么?
public MutableLiveData() {
super();
}
public LiveData() {
//mData保存我们发送的数据
mData = NOT_SET;
mVersion = START_VERSION;
}
2.添加观察者做了什么?
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//判断是否是主线程,否则报异常
assertMainThread("observe");
//判断当前界面是否销毁
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将livedata观察者和own封装到LifecycleBoundObserver
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//将新观察者缓存
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;
}
//为组件添加生命周期观察者
owner.getLifecycle().addObserver(wrapper);
}
LifecycleBoundObserver是什么?
从名字可以看出是将组件(Activity、fragment)的生命周期绑定到观察者上,看源码
//实现了LifecycleEventObserver
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
//当Activity的生命周期改变就会触发这个方法
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
}
3.发送数据做了什么
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
//将任务放到线程池里 并切换到主线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
postvalue其实就是切换到主线程并调用setValue发送数据
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//其实调用的也是setValue发送数据
setValue((T) newValue);
}
};
@MainThread
protected void setValue(T value) {
//不是主线程抛出异常
assertMainThread("setValue");
//记录数据发送次数
mVersion++;
//将发送的数据赋值给mData
mData = value;
//默认传null
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 {
//循环通知观察者
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) {
return;
}
//回调观察者前 判断观察者是否时active状态 否则不会回调onChanged方法
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//防止生命周期回调多次 多次触发onChanged方法
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//回调观察者onChaged方法
observer.mObserver.onChanged((T) mData);
}
到此一个基本流程结束,其实就是运用了观察者模式。首先注册观察者,然后将观察者缓存到一个map里。当收到数据时会遍历所有的观察者,判断可见性,如果可见就通知观察者更新。
问题
问题一:怎么观察生命周期状态?
livedata添加观察者时,会创建一个LifecycleBoundObserver,它是一个组件生命周期观察者,当生命周期改变时,会触发onStateChanged,然后LifecycleBoundObserver会判断生命周期是否是isActive去调用观察者更新。与其说livedata观察生命周期,不如说是通过LifecycleBoundObserver观察。
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
...
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
...
owner.getLifecycle().addObserver(wrapper);
}
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
继续看 activeStateChanged做了什么
void activeStateChanged(boolean newActive) {
...
//判断生命周期是否是可见的
if (mActive) {
dispatchingValue(this);
}
}
问题二:为什么可发送粘性事件?
在onCreat中发送数据,点击按钮再去注册观察者
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_livedata_code)
//发送数据
liveData.postValue("1111111111")
}
//按钮点击
fun sendData(view: View) {
//添加观察者
liveData.observe(this, Observer {
Log.i(TAG, "livedata---------------->$it");
})
}
结果成功打印
I/LiveDataCodeAcy: livedata---------------->1111111111
liveData.observe 会调用 owner.getLifecycle().addObserver(wrapper);
因为LifecycleBoundObserver 间接实现了LifecycleObserver 所以会回调onStateChange()方法,在此方法中会重新遍历所有可见的观察者,触发更新
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
//是否时Destory状态
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//是的 就从map里删除此观察者
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
void activeStateChanged(boolean newActive) {
if (mActive) {
//这里和setvalue一样调用了 dispatchingValue 参数是this
dispatchingValue(this);
}
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
do {
mDispatchInvalidated = false;
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;
}
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//重新调用观察者的onChanged方法
observer.mObserver.onChanged((T) mData);
}
所以发送数据的地方有两个地方
1.setValue()\postValue()
2.oberver()
问题三:当重新可见的时候会不会重新接收到数据?怎么做到的?
同理会触发LifecycleBoundObserver#onStateChanged(),然后重新遍历可见的观察者更新
问题四:触发多个生命周期方法,观察者会不会多次收到信息?怎么控制这块的?
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
利用mVersion来记录是否处理过这个数据
- mVersion、mLastVersion 初始值都是-1
- 当setValue mVersion++ 变成1,observer.mLastVersion >= mVersion不成立,mLastVersion 变成1,然后回调方法
- 当生命周期发生改变,回调此方法observer.mLastVersion = mVersion。所以就不会继续触发回调方法
- 再次有生命周期方法触发 也不会多次触发观察者回调方法
问题五:怎么多个Activity共用同一个Livedata?
class LiveDataUtils {
private lateinit var mLiveDataMap:MutableMap<String,MutableLiveData<Any>>
private constructor(){
mLiveDataMap = mutableMapOf()
}
companion object{
private val instance = LiveDataUtils()
fun getInstance():LiveDataUtils{
return instance
}
}
/**
* 1.保存
* 2.获取
*/
fun <T> with(key:String,clazz:Class<T>) : MutableLiveData<T>{
if(!mLiveDataMap.containsKey(key)){
mLiveDataMap[key] = MutableLiveData<Any>()
}
return mLiveDataMap[key] as MutableLiveData<T>
}
}
问题六:AActivity发送消息,BActivity注册能收到数据吗?
AActivity
livedata = LiveDataUtils.getInstance().with("login",String::class.java)
livedata.postValue("来自AActivity的message")
BActivity
livedata.observe(this, Observer {
Log.i(TAG, "twoActivity:$it");
})
打印
twoActivity:来自AActivity的message
答案是肯定的,和问题二一个道理。当BActivity observe时,会触发生命周期方法回调,然后遍历所有观察者更新
问题七:AActivity注册在BActivity#Oncreat()发送,Activity 会收到消息么?
AActivity
livedata.observe(this, Observer {
Log.i(TAG, "AActivity:$it");
})
BActivity # onCreate
livedata.postValue("来自BActivity的message")
打印
AActivity:来自BActivity的message
原因是在BActiviy#Oncreat(),Livedata认为Activity还是可见的
问题八:AActivity注册在BActivity#点击事件发送,Activity 会收到消息么
AActivity
livedata.observe(this, Observer {
Log.i(TAG, "oneActivity:$it");
})
BActivity # 方法中
livedata.postValue("来自twoActivity的message")
打印
无
因为当发送给观察者时会判断组件所处的生命周期
//回调观察者前 判断观察者是否时active状态 否则不会回调onChanged方法
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
当在oncreate中 livedata认为是可见状态,所以能收到。再方法中发送消息,这时候生命周期认为是不可见的 所以没有调用
网友评论