android ViewModel observe 在循环当中

我有一个不成熟的小问题: 我把某一个 viewmodel.somthing.observe(this,Oberserver){do sth with i } 放到一个循环里 比如 for(i in 0 ..9){ } 里面,为什么只观察,或者说只显示最后一个 i, 即10, 从1 到9 难道不观察,不显示。其中原理不明吧,希望赐教

如果是通过 viewmodel.somthing.observe(this,specificObserverInstance){do sth with i } 的形式注册的,实际上只显示的是第0个,从1-9的不观察。

可以看下 LiveData#observe(LifecycleOwner, Observer) 的源码:

    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {

        // omitted

        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

        // omitted

        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

每次注册 Observer 的时候都会检查下该 Observer 是否已经在 mObervers 里面了,如果已经在了,就直接返回了。

viewmodel.somthing.observe(this,specificObserverInstance){do sth with i } 这种方式,由于 specificObserverInstance 是同一个实例,所以该实例在循环的第0次就已经存放进入 mObervers 里面了,后面9次就直接返回了、并未注册成功。

在观察者序列中,每次添加新的观察者,都会去检查这个观察者是否在序列中。虽然你是在循环中去添加了,但是你的观察者是在循环外去生成的,所以你循环中引用了该对象十次,实际上每次添加的都是这个观察对象。 解决方案一、在循环中去new这个观察者。  方案二、重写ViewModel,将检查方法屏蔽掉。  但是实际上,想要观察一个持续变化的量的时候,不需要对同一个观察者添加多次,因此被观察者每变化一次,都会通知一次所有的观察者。这就是订阅模式的优点。

可以试试在每次循环中新建一个Observer示例,从而避免每次循环用同一个示例,类似这样:

for (i in 0...9) {
    viewmodel.somthing.observe(this,new Observer() {
        public void onChanged() {
            {do sth with i }
        }
    });

}

 

谢谢,感觉自己没写错啊,上一下我的循环:

可以看到我的favouriteWeatherLiveData 在 list 的循环中每次都是新建Observer,(还是我可能写错了)

上一下我的 favouriteViewModel

每次刷新refreshFavouriteWeather时,都会引起favouriteWeatherLiveData 的变化,但我却只能得到 list 里面最后一组数据。谢谢赐教