重装合成旅 發表於 2025-11-14 10:36:37

android RecycledViewPool的作用详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>一、先明确基础概念</li><li>二、为什么会&ldquo;频繁创建ViewHolder&rdquo;?</li><li>三、viewType和缓存池容量的关系</li><li>四、为什么&ldquo;调整RecycledViewPool容量&rdquo;能解决问题?</li><li>总结</li></ul></div><p class="maodian"></p><h2>一、先明确基础概念</h2>
<ul><li><code>RecycledViewPool</code> 是什么?
<ul><li>它是 <code>RecyclerView</code> 的&ldquo;缓存池&rdquo;,专门存储那些&ldquo;暂时用不到但可能后续复用&rdquo;的 <code>ViewHolder</code>。当 <code>ViewHolder</code> 从屏幕滑出,且超过 <code>mCachedViews</code>(另一级缓存)的容量时,会被转移到这里&ldquo;待命&rdquo;。</li></ul></li><li><code>RecycledViewPool</code> 的默认容量是多少?<ul><li>它的容量是按 <code>viewType</code> 划分的:默认情况下,每种 <code>viewType</code> 最多缓存 5 个 <code>ViewHolder</code>。</li><li>例如:如果列表有 2 种 <code>viewType</code>(类型 0 和类型 1),那么缓存池会为类型 0 最多存 5 个,类型 1 最多存 5 个,总容量是 10 个(但按类型隔离)。</li></ul></li><li><code>viewType</code> 是什么?<ul><li><code>viewType</code> 是 <code>RecyclerView</code> 用来区分不同 Item 布局的标识(由 <code>getItemViewType()</code> 方法返回)。不同 <code>viewType</code> 的 <code>ViewHolder</code> 不能互相复用(因为布局不同)。例如:文本 Item(<code>viewType=0</code>)和图片 Item(<code>viewType=1</code>)的 <code>ViewHolder</code> 无法混用。</li></ul></li></ul>
<p class="maodian"></p><h2>二、为什么会&ldquo;频繁创建ViewHolder&rdquo;?</h2>
<p>核心原因是:<code>RecycledViewPool</code> 中对应 <code>viewType</code> 的缓存不够用了,导致每次需要显示新 Item 时,都得重新创建 <code>ViewHolder</code>(调用 <code>onCreateViewHolder</code>)。</p>
<p>举个例子:<br />假设你的列表有一个高频出现的 <code>viewType=0</code>(比如 100 个 Item 都是这个类型),而 <code>RecycledViewPool</code> 为 <code>viewType=0</code> 的默认容量是 5 个。</p>
<ul><li>当快速滑动列表时,屏幕外会产生大量 <code>viewType=0</code> 的 <code>ViewHolder</code>,但缓存池最多只能存 5 个。</li><li>超过 5 个后,新滑出的 <code>ViewHolder</code> 会被直接销毁(因为缓存池满了)。</li><li>当你往回滑时,需要重新显示这些 <code>viewType=0</code> 的 Item,但缓存池里已经没有可用的了,只能重新创建 <code>ViewHolder</code>,导致 <code>onCreateViewHolder</code> 频繁调用,引发卡顿。</li></ul>
<p class="maodian"></p><h2>三、viewType和缓存池容量的关系</h2>
<p><code>RecycledViewPool</code> 的容量是按 <code>viewType</code> 独立分配的,不同 <code>viewType</code> 的缓存互不干扰。这意味着:</p>
<ul><li>如果某个 <code>viewType</code> 的 Item 数量特别多(高频出现),但缓存池为它分配的默认容量(5 个)不够用,就会频繁创建新 <code>ViewHolder</code>。</li><li>反之,如果某个 <code>viewType</code> 的 Item 很少(低频出现),即使缓存池容量是 5 个,也可能用不完(不会浪费)。</li></ul>
<p>例如:</p>
<ul><li>列表有两种 <code>viewType</code>:<code>viewType=0</code>(90% 的 Item 都是它)和 <code>viewType=1</code>(仅 10% 的 Item)。</li><li>默认情况下,两者各有 5 个缓存位。但 <code>viewType=0</code> 的 Item 太多,5 个缓存根本不够,导致频繁创建;而 <code>viewType=1</code> 的 5 个缓存可能一直用不完。</li></ul>
<p class="maodian"></p><h2>四、为什么&ldquo;调整RecycledViewPool容量&rdquo;能解决问题?</h2>
<p>当我们为高频出现的 <code>viewType</code> 增大缓存容量(比如从默认 5 个调到 10 个),意味着:</p>
<ul><li>更多滑出屏幕的 <code>ViewHolder</code> 能被存到缓存池里,而不是被销毁。</li><li>当再次需要显示该类型的 Item 时,能直接从缓存池里取到 <code>ViewHolder</code> 复用,无需重新创建(减少 <code>onCreateViewHolder</code> 的调用)。</li></ul>
<p><strong>代码示例</strong>:</p>
<div class="jb51code"><pre class="brush:java;">// 为高频出现的 viewType=0 扩容到 10 个缓存
recyclerView.getRecycledViewPool().setMaxRecycledViews(0, 10);</pre></div>
<p>这样,<code>viewType=0</code> 的 <code>ViewHolder</code> 缓存容量从 5 变成 10,能容纳更多暂时不用的 <code>ViewHolder</code>,大幅降低创建新实例的频率。</p>
<p class="maodian"></p><h2>总结</h2>
<ol><li>频繁创建 <code>ViewHolder</code> 的原因:高频出现的 <code>viewType</code> 对应的缓存池容量不足(默认 5 个),导致滑出屏幕的 <code>ViewHolder</code> 被销毁,再次需要时只能重新创建。</li><li><code>RecycledViewPool</code> 默认容量:每种 <code>viewType</code> 最多缓存 5 个 <code>ViewHolder</code>。</li><li>与 <code>viewType</code> 的关系:缓存池按 <code>viewType</code> 隔离,不同类型的 <code>ViewHolder</code> 不能复用,因此高频类型需要更大的缓存容量。</li></ol>
<p>通过为高频 <code>viewType</code> 增大缓存池容量,能提升复用率,减少 <code>ViewHolder</code> 创建次数,优化列表滑动性能。</p>
<p>到此这篇关于android RecycledViewPool的作用的文章就介绍到这了,更多相关android recycledviewpool内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: android RecycledViewPool的作用详解