想验证下,在不同的fragment中观察同一个liveData。于是先用同一个fragment类创建多个对象测试。结果是不行。同时遇到了如下报错。
报错:
java.lang.IllegalArgumentException: Cannot add the same observer with different lifecycles
at androidx.lifecycle.LiveData.observe(LiveData.java:179)
发生场景:
同一个activity (ActivityA), 下面多个相同fragment(FragmentB)的不同对象,fragment 有基于activity 的ObservableViewModel子类(YourVM),VM里面有MutableLiveData<String>(liveData)。
在FragmentB中,对liveData进行观察observe就会发生以上奔溃。
vm = ViewModelProviders.of(this.activity!!).get(YourVm::class.java)
vm?.liveData?.observe(this, Observer {
if(it!=null) {
//todo 你的逻辑
}
})
这里的observe(this, Observer),this是fragment,那么就符合错误提示说的: 同一个livedata (用的都是activity中的,一般用于activity与fragment数据共享),不同的生命周期(不同的fragment对象)。
查看源码:看到,observe一定要在主线程。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
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);
}
putIfAbsent 方法,根据方法名知道,是如果没有才put ;有这个key ,则直接返回value。
/**
* If the specified key is not already associated
* with a value, associates it with the given value.
*
* @param key key with which the specified value is to be associated
* @param v value to be associated with the specified key
* @return the previous value associated with the specified key,
* or {@code null} if there was no mapping for the key
*/
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;
}
这里的obsever 是存在,并且没有加到新的fragment中,所以抛出了这个IllegalArgumentException。
LiveData 观察,是只有变化才回调。
针对这种情况,就需要在activity中观察变量变化。同时,对于同一个liveData变量,在不同fragment对象中有不同的处理,可以获取到fragment对象,通过方法回调做不同处理。
网友评论