1

短篇小说: 我有一个(预缓存)CustomLinearLayoutManagerRecyclerView、 CustomRecyclerView.Adaptor、 CustomRecyclerView.ViewHolder设置。我只有一个 viewType 和轻量级绑定函数。它真的没什么特别的,这就是为什么我希望我不需要发布代码。我也不想与所有不相关的代码混淆。

我遇到的问题是,尽管没有回收任何视图,但仍然偶尔调用 onCreateViewHolder(在初始行膨胀之后),这让我想知道也许我有内存泄漏?你认为是这样吗?为什么?是什么决定了我的应用仍然需要创建更多视图而不是回收?

我将添加一件事,可能会以某种方式考虑在内。我的行有两种视觉状态(它们展开和折叠),看起来在不同状态下更随机地混合行会使问题恶化。

全文: 我注意到我的RecyclerView. 使用 android studio 的分析器,我注意到以下几点:

  1. 我所有的bindViewHolder方法都非常快,并且不会阻碍滚动。
  2. OnCreateViewHolder是什么导致口吃。这就解释了为什么在第一次滚动时总是有一些口吃。此外,它的通货膨胀占 CPU 时间的比例高得离谱。
  3. 使用 构建项目/行布局ConstraintLayout时,onMeasure函数性能不佳,破坏了较弱设备上的滚动性能。
  4. 使用LinearLayouts 构建项目/行布局后,性能显着提高。然而,观点的膨胀仍然需要足够长的时间来引起轰动。

有了这些信息,我尽可能简化了我的行项目的布局,确保使用LinearLayouts. 无论如何,recyclerview 的项目的呈现不应该在第一个项目出现在屏幕上后导致口吃,因为一个,行都是相同的,除了绑定到它们的数据和两个,RecyclerView应该回收行。所以onCreateViewHolder最初应该被调用很多,然后很少再次调用。预缓存呢?我发现这是滚动时请求新视图的原因之一。我设置了缓存并创建了一个自定义LinearLayoutManager,该自定义覆盖了名为的预缓存(预取?)方法getExtraLayoutSpace(RecyclerView.State state)并调整这两者,以便有足够的现有可回收视图来覆盖滚动期间的请求。我的测试证实,在初始滚动后,转换​​到滚动状态时不会请求新视图。

所有这一切,我还有两个问题。其中一个onCreateViewHolder是在使用应用程序期间经常被调用,这会导致一些小问题。我在Log.w()里面放了一个onFailedToRecycleView()视图,以查看任何视图都没有被回收,看起来视图正在被回收。所以现在我认为存在一些内存泄漏,并且内存分析器显示在调用时经常发生内存使用量的跳跃onCreateViewHolder

4

1 回答 1

0

我在哪里发布的三个问题,

  1. 是否因为 Recyclerview 不断创建 Viewholder 而导致内存泄漏?
  2. 为什么我有内存泄漏?
  3. 是什么决定了我的应用仍然需要创建更多视图而不是回收?

我相信我基本上已经找到了 3 个问题中的 2 个或相应的潜在问题的解决方案。

里面Recyclerview的类是一个Recycler类和RecycledViewPool类。内部Recycler对象是向RecycledViewPool对象发出请求以回收可用的分离的废料查看器(如果它还没有附加的废料查看器要回收)。具体来说,对可回收视图的搜索发生在Recycler'sgetViewForPosition(int position)函数内部。如果(在此函数内)未找到可回收视图,则mAdapter.createViewHolder(RecyclerView.this, type)调用该视图。这导致onCreateViewholder被调用。所以要回答第三个问题,Recycler 正在决定何时调用 onCreateViewholder。

请注意,RecycledViewPool的工作是维护分离的废料视图持有者的数组列表(每个视图类型的数组列表的 1d 数组)。维护函数包括clear()reset()setMaxScrap(int viewType, int max),它们的作用与它们的名称相同。因此,解决第二个问题的途径是创建一个自定义 RecycledViewPool 来指示何时清除或减少了废品列表,以便我可以跟踪废品视图的创建和销毁。至于问题1,这可以通过使用来解决setMaxScrap(int viewType, int max)。此外,在 recyclerview 初始化时,我们可以在池中添加一些额外的 scrapview,并尝试保持最少数量的 scrapview,这可能通过监听器来完成。

于 2019-03-02T21:30:32.317 回答