同一个LiveData观察者绑定不同的生命周期

2020-10-14  本文已影响0人  王家匀匀

想验证下,在不同的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对象,通过方法回调做不同处理。

上一篇 下一篇

猜你喜欢

热点阅读