【问题标题】:RecyclerView ANR during fast fling快速投掷期间的 RecyclerView ANR
【发布时间】:2022-08-06 06:37:09
【问题描述】:

我有一个 RecyclerView (1.2.1),带有一个 List 适配器和 ViewHolder,由 Room PagingSource 支持。清单上有大约 700 项。分页似乎工作正常,我已经尽可能地扁平化了我的视图层次结构。

最初加载回收站视图时,一切似乎都很好。分页工作,一切似乎都很活泼。我的适配器中的onCreateViewHolder 被调用了 14 次,最初在屏幕上可见 5 次。

较慢的滚动很好(它确实比我预期的更频繁地调用onCreateViewHolder,但没有卡顿)。

快速浏览列表时会出现问题。经过 3-5 次快速投掷后,它似乎决定需要更多缓存的视图持有者,并多次调用 onCreateViewHolder - 此方法的计时时间约为 5 毫秒,但太多了他们,滚动停止。它似乎调用了onCreateViewHolder ~700 次 - 与列表中的项目数相同,就像它根本没有回收视图一样。

到那时,有时应用程序会恢复,那时一切都很顺利,似乎不需要创建更多的 ViewHolders。但有时我会收到 ANR 对话框。

我尝试过调整recyclerView.recycledViewPool.setMaxRecycledViews(),但这似乎不会增加recycledViewCount,直到大众onCreateViewHolder 来电。

我能做些什么来解决这个问题吗?让投掷速度变慢?以某种方式调整视图持有者回收,使其不会发疯并尝试一次创建这么多?

考虑到我的设计和数据限制,我认为我无法更好地实现布局膨胀。即使我可以,它仍然会产生太多无法在 16 毫秒内完成的任务!

  • 难道是你的一些内在逻辑onCreateViewHolder可以调整/更优化?
  • 我愿意:MyViewHolder(LayoutInflater.from(...)) MyViewHolder 创建本身几乎不需要任何时间——它所做的只是大约十几个 itemView.findViewById 调用并查找几种颜色——发生在几微秒内。大部分时间来自布局膨胀。
  • 例如,6059 微秒用于视图膨胀,42 微秒用于创建视图持有者。
  • 绑定需要 0.25-2 毫秒,FWIW。
  • 请分享代码,如果没有代码共享,任何描述都无法显示真正的问题。

标签: android android-recyclerview


【解决方案1】:

在我的情况下,我需要做两件事。首先,我需要调整我的分页配置。我的prefetchDistance 与我的页面大小相比太小了!这摆脱了 ANR - 不再大量创建 ViewHolders!

recyclerView 在加载页面时仍会暂停滚动(尤其是接近尾声时)。我添加了一个loadStateFlow 收集器来处理显示加载指示器,以便用户知道还有更多数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 2020-06-19
    相关资源
    最近更新 更多