Android踩坑经验-notifyDataSetChanged列表不刷新问题分析

本文主要阐述在使用RecyclerView中遇到notifyDataSetChanged列表不刷新问题,表现是:列表滑动时,notifyDataSetChanged可以正常刷新界面,但Fragment切换Tab后,再次滑动RecycleView,列表不刷新。
通过打断点调试,发现数据请求没有问题,每次滑动到底部时自动请求数据,在数据集上添加网络数据,通过打断点信息可得到size由20变为40,数据没有问题:
在这里插入图片描述
先看下notifyDataSetChanged实现:

public final void notifyDataSetChanged() {
            mObservable.notifyChanged();
 }

比较明显,观察者模式实现,数据改变了,通知观察者刷新。如果不刷新了,有几个怀疑点:
1:数据地址变了,不是同一个对象
打个比方:在数据A上注册了观察者,后面我们更改了数据B,然后调用了notify,此时必然列表不更新,常见的问题及解决办法:

list = data;
notifyDataSetChanged;

改为

list.clear();
list.addAll(data);
notifyDataSetChanged;

2:recycleview地址变了,不是同一个对象
情况类似1,只是由数据换成了recycleview,观察者不是同一个了,此时notify,更新的不是当前recycleView实例,因此必然看不到界面刷新。
此问题需要结合业务去看,主要通过打断点去看,notifyDataSetChanged时是否是同一个对象
3:数据和recycleview都是同一个地址,但绑定关系不在了
打个比方,数据A上注册了recycleview R,然后经过其他操作(如切换ntab),在切换tab声明周期中,无意间调用了unregisterAdapterDataObserver,导致A和R的绑定关系不在了,因此R不再刷新,
本次遇到的问题正好是情况3,单步调试下看下结果:
在这里插入图片描述
recyclerView和dataSource地址都没变(主要看@后面的数字),然后再notifyDataSetChanged处加断点,看内部执行情况,发现:
在这里插入图片描述
观察者的List为空了,按照猜测,肯定是无意间调用了unregisterAdapterDataObserver,导致数据和RecycleView绑定关系不在了,因此在unregisterAdapterDataObserver处打断点:
在这里插入图片描述
发现在封装时,在onDetachedFromWindow中无意间调用了unregisterAdapterDataObserver,问题根源已找到,解决办法:
unregisterAdapterDataObserver调用可以用标志位来控制,业务在使用封装的recycleview时,复写此标志位,用来控制是否unregister,这个地方需小心Recycleview的泄漏问题。

猜你喜欢

转载自blog.csdn.net/longlong2015/article/details/88826057