短篇小说:
我有一个(预缓存)自定义LinearLayoutManager
,RecyclerView
,自定义RecyclerView.Adaptor
,自定义RecyclerView.ViewHolder
设置。我只有一个viewType和轻量级绑定函数。真的没什么特别的,这就是为什么我希望不需要发布代码。我也不想混淆所有不相关的代码。
我遇到的问题是,尽管没有回收任何视图,但仍会偶尔调用onCreateViewHolder(在初始行膨胀之后),这让我想知道我是否存在内存泄漏?您认为是这种情况,为什么?是什么决定了我的应用仍然需要创建更多视图而不是回收?
我将添加一件事,也许以某种方式考虑在内。我的行具有两种视觉状态(它们分别处于展开和折叠状态),并且看起来在不同状态下行的随机混合似乎使问题更加恶化。
全文:
我已经注意到RecyclerView
平滑滚动时偶尔会出现打h。使用android studio的探查器,我注意到了以下几点:
bindViewHolder
方法都非常快,并且不会阻止滚动。OnCreateViewHolder
是造成口吃的原因。这就解释了为什么在第一次滚动过程中总是会出现一些口吃的现象。而且,其通货膨胀占CPU时间的比例高得离谱。ConstraintLayout
构建的项目/行布局,onMeasure
函数的性能较差,破坏了较弱设备上的滚动性能。LinearLayout
构造的项目/行布局,性能得到了极大的提高。但是,视图膨胀仍然需要足够长的时间才能引起问题。借助此信息,我尽可能地简化了行项目的布局,确保使用LinearLayout
。无论如何,在第一个项目出现在屏幕上之后,recyclerview的项目的呈现不应导致结结,因为其中一个,除了绑定到它们的数据外,其他所有行都相同,另外两个,RecyclerView
应该回收行。因此onCreateViewHolder
应该先被大量调用,然后再很少被调用。那预缓存呢?我发现这是滚动时需要新的视图持有者的原因之一。我设置了缓存并创建了一个自定义LinearLayoutManager
,该自定义getExtraLayoutSpace(RecyclerView.State state)
覆盖了称为onCreateViewHolder
的预缓存(预取?)方法,并对其进行了调整,以便在滚动过程中有足够的可回收视图来满足请求。我的测试证实,在初始滚动之后,过渡到滚动状态时将请求新视图。
所有这些和我还有两个问题。其中之一是Log.w()
在使用该应用程序期间经常被调用,这会引起一些打h。我将onFailedToRecycleView()
放在onCreateViewHolder
内,以查看是否没有回收任何视图,并且看起来好像在回收视图。因此,现在我认为存在一些内存泄漏,并且内存分析器显示了在调用<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<% include ../../partials/nav.ejs %>
<h1>Hello</h1>
<h4><%= uid %></h4>
</body>
</html>
时经常发生的内存使用情况跳跃。
答案 0 :(得分:0)
我张贴在哪里的三个问题
我相信我已经找到了3个问题中的2个或相应潜在问题的解决方案。
内部Recyclerview
类是Recycler
类和RecycledViewPool
类。 内部Recycler
对象向RecycledViewPool
对象发出请求,要求其提供一个可用的分离的废料查看器进行回收 (如果尚未附加)废弃回收站。特别是,这种对可回收视口的搜索是在Recycler
的{{1}}函数内部进行的。如果(在此函数内)找不到可循环使用的视图,则调用getViewForPosition(int position)
。这导致mAdapter.createViewHolder(RecyclerView.this, type)
被调用。因此,为了回答第三个问题,Recycler正在决定何时调用onCreateViewholder。
请注意,onCreateViewholder
的工作是维护一个由拆下的废料视图支架组成的数组列表数组(每个viewType的数组列表的1d数组)。维护功能包括RecycledViewPool
,clear()
和reset()
,它们的作用与名称相同。因此,解决第二个问题的途径是创建一个自定义的RecycledViewPool,它指示何时清除或减少剪贴簿列表,以便我可以跟踪剪贴簿视图的创建和销毁。至于问题1,可以使用setMaxScrap(int viewType, int max)
解决。另外,在初始化recyclerview时,我们可以在池中添加一些额外的scrapview,并尝试维持最小数量的scrapview,而这可能可以由侦听器完成。