给出两个自己写的ViewModel:
public class MyViewModel extends AndroidViewModel implements Serializable {
public static MyMutableLiveData<String> mAccount;
public MyViewModel(@NonNull Application application) {
super(application);
mAccount = new MyMutableLiveData<>();
}
public void setAccount(String account){
mAccount.setValue(account);
}
@Override
protected void onCleared() {
super.onCleared();
}
public static Observer<String> observer = new MyObserver<String>();
public static class MyObserver<T> implements Observer<T>,Serializable{
@Override
public void onChanged(T t) {
Log.e("mvvmAccount","1234");
}
}
public class MyMutableLiveData<T> extends MutableLiveData<T> implements Serializable{
}
}
vm.mAccount.observe(this,vm.observer);这样调用
这样写可以在activity销毁的时候可以连带这个observer一起保留下来。
public class MyViewModel extends AndroidViewModel{
public MutableLiveData<String> mAccount;
public MyViewModel(@NonNull Application application) {
super(application);
mAccount = new MutableLiveData<>();
}
public void setAccount(String account){
mAccount.setValue(account);
}
@Override
protected void onCleared() {
super.onCleared();
}
}
只能这样调用:
vm.mAccount.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
}
});
先提出几个问题:
1.这两种observe的写法会造成什么影响:
第一种写法可以在activity销毁的时候可以连带这个observer一起保留下来
第二种其实每次都是new了新的observer
2.如果一个LiveData已经observe一次了,再observe一次会发生什么情况,为什么:
这个情况比较复杂分为:
a.在同一个activity(lifecycle)中使用同一个viewmodel和livedata来observe同一个observer
b.在同一个activity(lifecycle)中使用同一个viewmodel和livedata来observe不同的observer
c.在不同的activity(lifecycle)中使用同一个viewmodel和livedata来observe同一个observer
d.在不同的activity(lifecycle)中使用同一个viewmodel和livedata来observe不同的observer
3.为什么在activity意外销毁重建比如横竖屏的时候重建后会立刻调用一次livedataObserver的onchange方法:
好了带着这些问题来看源码:
首先讲正常流程,在这个正常流程的源码中会有我自己理解的注释:
LiveData的setValue方法:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//这个mVersion特别重要大家记一下,在Livedata对象中维护这样一个int值
//变量每次setValue都会加一,而且只会在这里变化,初始化在livedata的构造方法
mVersion++;
mData = value;
//这个方法特别重要,这个会调用到observer的onchange方法
dispatchingValue(null);
}
START_VERSION 初始值是-1
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;
}
紧接着就是dispatchingVaule方法:
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
//dispatchingValue方法总共有两个地方调用一个是setValue一个activeStateChanged
//一个是上面setValue方法参数是null,也就是说会走下面
//另一种情况就是生命周期变化的时候,变为active的时候
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//下面会把livedata所有observe的observer都调一遍,重点是mObservers这个参数
//所以有时候你setValue一次却调用了几个地方有可能就是observe了很多不同的observer
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
继续往下调用considerNotify:
private void considerNotify(ObserverWrapper observer) {
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.
//这里其实就是一个异常判断,如果lifecycle现在不是active状态那就给mActive
//手动置成false
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//之前提到的mVersion,那observer.mLastVersion是什么,在什么时候赋值改变
//这个判断能起到什么作用 下面会分析到 非常重要
if (observer.mLastVersion >= mVersion) {
return;
}
//除了赋初值只有这里会和mVersion同步一下
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
上面就是从setValue到回调onchanged方法的全部流程
下面详细分析一下observer.mLastVersion:
observer是observerWrapper的子类LifecycleBoundObserver的实例,我们在livedata中用的都是LifecycleBoundObserver,这个比较重要稍后分析
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
//这里就是mLastVersion赋初值的地方,也是START_VERSION -1,那在哪里new 的
//observerWrapper的子类呢,是在observe方法里new LifecycleBoundObserver的时候
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
//这个方法最下面调用了dispatchingValue方法,这就是第二处调用dispatchingValue方法的地
//方,具体调用时机是在lifecycle变为active的时候,稍后分析
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.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
接下来看LifecycleBoundObserver的使用:在livedata.observe的时候调用的
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//这里非常重要 每次都会new一个新的ObserverWrapper这时后mLastVersion就赋予了初值-1
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//这里能解决上面2.c问题,如果一个Livedata已经observe了一个lifecycle还要想observ另一
//个lifecycle那就会抛异常crash
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//这里能解决上面2.a,如果一个Livedata已经observe了一个lifecycle还要再次observe这个
//lifecycle就会直接return。
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
//详细介绍mobserver
mobserver是啥:是一个map
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
//这里就是上面调用的方法,他会先查看有没有这个(observer,wrapper)的entey,有直接返回没有才存到map中
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;
}
这里在注释中解决了2.a和2.c
下面解释mVersion判断的作用:
if (observer.mLastVersion >= mVersion) {
return;
}
这个observer是ObserverWrapper,在leveData中其实就是LifecycleBoundObserver。
1.在livedata第一次observe的时候,这时lifecycle处于active状态会调用到activeStateChanged方法(在activiey或fragment中调用observe,lifecycle是active的会触发这个activeStateChanged方法)然后调用dispatchingValue(this);然后一步步调用到considerNotify方法这时被这个条件拦住了,因为这时候mversion是在livedata初始化的时候赋得初值为-1,而LifecycleBoundObserver也是新new的所以observer.mLastVersion值也是-1这时这里直接return了,所以我们第一次observe不会直接触发onchange方法
2.在setVaule的时候,mVersion加一在这里判断不成立会走到下面调用onchange方法
3.回答2.b问题:在同一个activity(lifecycle)中使用同一个viewmodel和livedata来observe不同的observer
因为是不同的oberver所以在livedata的observe方法中会new一个 LifecycleBoundObserver mLastVersion为-1,并且因为observer不同所以能走到最后一句addobserver,observe后lifecycle是active直接会调用到activeStateChanged方法,然后一步步执行到considerNotify方法,在判断observer.mLastVersion>=mVersion的时候observer.mLastVersion为-1,如果livedata已经调用过setValue方法那mVersion就大于-1这时会直接调用observer的onchange方法.
4.回答问题2.d和: own和observer全变了,所以执行liveData的observe方法会会new一个 LifecycleBoundObserver mLastVersion为-1,然后从observs的map中查找不到就addobserver之后和上面的流程一样。
回答问题3:先上一段代码
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//在activity异常销毁的时候就走这里就移除掉了observer
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
在销毁的时候移除了observer,重建activity的时候就会重新添加,在observers中没有查找到,就addobserver,然后和上面的流程一样了
activeStateChanged方法如何在lifecycle变化时调用并且是如何处理的:
调用:
处理:
就是newActive和mActive的一个转换,如果之前mActive是false,newActive是true的时候:由非active变成active的时候,因为if (mActive) { dispatchingValue(this); }这个判断就会调用到dispatchingValue,如果由active变成非active就不会执行仅仅保存了状态.