短篇小说:
我有一个(预缓存)CustomLinearLayoutManager
、RecyclerView
、 CustomRecyclerView.Adaptor
、 CustomRecyclerView.ViewHolder
设置。我只有一个 viewType 和轻量级绑定函数。它真的没什么特别的,这就是为什么我希望我不需要发布代码。我也不想与所有不相关的代码混淆。
我遇到的问题是,尽管没有回收任何视图,但仍然偶尔调用 onCreateViewHolder(在初始行膨胀之后),这让我想知道也许我有内存泄漏?你认为是这样吗?为什么?是什么决定了我的应用仍然需要创建更多视图而不是回收?
我将添加一件事,可能会以某种方式考虑在内。我的行有两种视觉状态(它们展开和折叠),看起来在不同状态下更随机地混合行会使问题恶化。
全文:
我注意到我的RecyclerView
. 使用 android studio 的分析器,我注意到以下几点:
- 我所有的
bindViewHolder
方法都非常快,并且不会阻碍滚动。 OnCreateViewHolder
是什么导致口吃。这就解释了为什么在第一次滚动时总是有一些口吃。此外,它的通货膨胀占 CPU 时间的比例高得离谱。- 使用 构建项目/行布局
ConstraintLayout
时,onMeasure
函数性能不佳,破坏了较弱设备上的滚动性能。 - 使用
LinearLayout
s 构建项目/行布局后,性能显着提高。然而,观点的膨胀仍然需要足够长的时间来引起轰动。
有了这些信息,我尽可能简化了我的行项目的布局,确保使用LinearLayout
s. 无论如何,recyclerview 的项目的呈现不应该在第一个项目出现在屏幕上后导致口吃,因为一个,行都是相同的,除了绑定到它们的数据和两个,RecyclerView
应该回收行。所以onCreateViewHolder
最初应该被调用很多,然后很少再次调用。预缓存呢?我发现这是滚动时请求新视图的原因之一。我设置了缓存并创建了一个自定义LinearLayoutManager
,该自定义覆盖了名为的预缓存(预取?)方法getExtraLayoutSpace(RecyclerView.State state)
并调整这两者,以便有足够的现有可回收视图来覆盖滚动期间的请求。我的测试证实,在初始滚动后,转换到滚动状态时不会请求新视图。
所有这一切,我还有两个问题。其中一个onCreateViewHolder
是在使用应用程序期间经常被调用,这会导致一些小问题。我在Log.w()
里面放了一个onFailedToRecycleView()
视图,以查看任何视图都没有被回收,看起来视图正在被回收。所以现在我认为存在一些内存泄漏,并且内存分析器显示在调用时经常发生内存使用量的跳跃onCreateViewHolder
。