RecyclerView缓存机制梳理
RecyclerView为了提高列表滚动时的性能,设计了一套高效的缓存机制,主要通过多级缓存来复用和存储视图。以下是该缓存机制的具体工作方式:
1. Scrap Cache(废弃缓存)
- mAttachedScrap:
- 存储当前屏幕中但即将被移除的ViewHolder。
- 这些ViewHolder仍与RecyclerView的父布局保持连接,但已不可见。
- 查找可重用ViewHolder的首选位置。
2. View Cache(视图缓存)
- mCachedViews:
- 存储已从屏幕上移除但状态未变的ViewHolder。
- 默认大小为2,可自定义。
- 当mAttachedScrap无可用ViewHolder时,从此处查找。
- 遵循FIFO原则管理缓存大小。
3. 开发者自定义缓存
- mViewCacheExtension:
- 可选缓存层,允许开发者自定义缓存策略。
- 适用于需要特殊缓存逻辑的高级场景。
4. RecyclerViewPool(回收池)
- mRecyclerPool:
- 缓存Item的最终站,保存Removed、Changed及mCachedViews溢出项。
- 使用SparseArray按ViewType存储ArrayList。
- 每个ArrayList默认最多存5个ViewHolder。
- ViewHolder在回收时清理内部数据,需重新绑定。
缓存查找顺序
- mAttachedScrap:查找刚剥离的ViewHolder。
- mCachedViews:进行精确匹配查找。
- mRecyclerPool:从回收池中查找。
- createViewHolder:若缓存中无可用ViewHolder,则创建新的。
优化策略
- 减少视图层级、预加载、共享视图等策略可进一步提升性能。
拓展一:关于ViewHolder
ViewHolder是Android开发中RecyclerView控件的一个重要组件,它主要用于缓存和复用列表项的视图,以提高列表的滚动性能和流畅度。以下是对ViewHolder的详细解释:
定义与功能
- 定义:ViewHolder是一个静态的内部类,通常继承自
RecyclerView.ViewHolder。它用于缓存每个列表项(item)的视图(View)对象,以避免在滚动时重复调用findViewById()方法,从而提高性能。 - 功能:
- 缓存视图:ViewHolder通过持有列表项的视图对象,实现视图的缓存。当列表项滚出屏幕后,其对应的ViewHolder会被保存起来,以便后续复用。
- 减少findViewById调用:在RecyclerView的
onBindViewHolder()方法中,通过ViewHolder可以直接访问到列表项的视图对象,而无需每次都调用findViewById()来查找视图,从而减少了不必要的查找操作,提高了性能。 - 支持复杂布局:ViewHolder可以支持复杂的列表项布局,通过绑定不同的视图和数据,实现多样化的列表项展示。
使用方式
- 定义ViewHolder:通常会在RecyclerView的Adapter中定义一个静态的内部类ViewHolder,并在其中定义与列表项视图相关的字段和方法。
- 创建ViewHolder:在Adapter的
onCreateViewHolder()方法中,通过LayoutInflater加载列表项的布局文件,并将其传递给ViewHolder的构造函数,从而创建ViewHolder实例。 - 绑定ViewHolder:在
onBindViewHolder()方法中,将ViewHolder与特定的数据项绑定,并更新视图以显示这些数据。
示例代码
以下是一个简单的ViewHolder示例代码:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<String> mData;
public MyAdapter(List<String> data) {
mData = data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_list_item, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
String item = mData.get(position);
holder.myTextView.setText(item);
}
@Override
public int getItemCount() {
return mData.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView myTextView;
public MyViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.my_text_view);
}
}
}
在这个示例中,MyViewHolder类继承自RecyclerView.ViewHolder,并持有一个TextView的引用。在onCreateViewHolder()方法中,我们加载了列表项的布局文件,并将其传递给MyViewHolder的构造函数。在onBindViewHolder()方法中,我们将ViewHolder与特定的数据项绑定,并更新了TextView的文本内容。
总结
ViewHolder是RecyclerView中用于缓存和复用列表项视图的重要组件。通过减少findViewById()的调用次数和支持复杂布局,ViewHolder显著提高了列表的滚动性能和用户体验。在Android开发中,合理使用ViewHolder是优化RecyclerView性能的关键之一。
拓展二:Android三级缓存策略
Android应用中常见的三级缓存策略用于管理图片等资源,以提高性能和用户体验:
-
内存缓存:
- 优先级最高,速度最快。
- 加载图片时首先检查内存缓存。
-
本地缓存:
- 内存缓存未命中时,尝试从本地(如SD卡)加载。
- 速度次于内存缓存,但可作为备选方案。
-
网络缓存:
- 优先级最低,从网络下载图片。
- 受网络状况影响,速度最慢。
注意事项
- 缓存的清理和管理至关重要,避免占用过多存储空间或造成内存泄漏。
- 合理的缓存策略能显著减少不必要的网络请求,提升应用性能。
通过结合RecyclerView的缓存机制和Android的三级缓存策略,开发者可以构建出高效、流畅的用户界面。