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

 
本文主要阐述在使用RecyclerView中遇到notifyDataSetChanged列表不刷新问题,表现是:列表滑动时,notifyDataSetChanged可以正常刷新界面,但Fragment切换Tab后,再次滑动RecycleView,列表不刷新。
通过打断点调试,发现数据请求没有问题,每次滑动到底部时自动请求数据,在数据集上添加网络数据,通过打断点信息可得到size由20变为40,数据没有问题:
先看下notifyDataSetChanged实现:
public final void notifyDataSetChanged() {
            mObservable.notifyChanged();
 }
123
比较明显,观察者模式实现,数据改变了,通知观察者刷新。如果不刷新了,有几个怀疑点:
1:数据地址变了,不是同一个对象
打个比方:在数据A上注册了观察者,后面我们更改了数据B,然后调用了notify,此时必然列表不更新,常见的问题及解决办法:
list = data;
notifyDataSetChanged;
12
改为
list.clear();
list.addAll(data);
notifyDataSetChanged;
123
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的泄漏问题。
————————————————
版权声明:本文为CSDN博主「longlong2015」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/longlong2015/java/article/details/88826057
posted @ 2020-06-04 11:13  新感觉  阅读(3445)  评论(0编辑  收藏  举报