RecyclerView在快速滑动时ANR

3
我有一个RecyclerView(1.2.1),使用List adapter和ViewHolder,并由Room PagingSource支持。列表中有大约700个项目。分页似乎正常工作,并且我已尽可能地减少了View层次结构的嵌套。
在刚开始加载RecyclerView时,一切都很好。分页工作正常,一切看起来流畅。适配器中的onCreateViewHolder被调用了14次,并且最初在屏幕上显示了5个。
滑动速度较慢也没有问题(它比我预期的调用了onCreateViewHolder函数更多,但没有任何卡顿)。
问题出现在快速滑动列表时。在3-5个快速滑动后,它似乎决定需要具有更多缓存的view holder,并且会多次调用onCreateViewHolder——该方法的时间为~5ms,但调用次数太多,滚动停止了。它似乎会调用onCreateViewHolder ~700次——与列表项数量相同,就像根本没有回收视图一样。
此时,有时应用程序将恢复正常,此时一切都很流畅,而且似乎不需要创建更多ViewHolders。然而,有时我会得到ANR对话框。
我已经尝试过调整recyclerView.recycledViewPool.setMaxRecycledViews(),但这似乎无法增加recycledViewCount,直到进行大量的onCreateViewHolder调用之后。
是否有任何办法解决这个问题?使滑动速度更慢?调整视图持有者回收方式,以便它不会发疯并试图一次创建那么多?
考虑到我的设计和数据限制,我认为无法改进布局膨胀。即使我可以,也创建了太多内容,无法在16ms内完成!

你的 onCreateViewHolder 中是否存在可调整/更优化的内部逻辑呢? - Daniel
我执行:MyViewHolder(LayoutInflater.from(...))创建 MyViewHolder 本身几乎不需要时间 - 它只是进行了大约十几个 itemView.findViewById 调用和查找了一些颜色 - 只需几微秒即可完成。绝大部分时间来自于布局膨胀。 - Mark
绑定需要0.25-2毫秒,顺便说一下。 - Mark
听起来很有趣,我会检查将一些代码移动到后台线程的可能性,并查看其行为,例如检查Executor,例如 protected Executor myExecutor = Executors.newSingleThreadExecutor(); - Daniel
3
请分享代码,如果没有共享代码,那么没有描述可以展示真正的问题。 - Amirhosein Rostami
显示剩余4条评论
1个回答

1
在我的情况下,我需要做两件事情。首先,我需要调整我的分页配置。相对于我的页面大小,我的 prefetchDistance 太小了!这样就摆脱了 ANR - 不再大量创建 ViewHolders 了!
当加载页面时(特别是接近末尾时),recyclerView 仍会暂停滚动。因此,我添加了一个 loadStateFlow 收集器来处理显示加载指示器,这样用户就知道还有更多数据要来了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接