RecycledViewPool的使用和堆内存分析
RecycledViewPool在
ViewPager+RecyclerView的场景下可以大放光彩。
下面就来验证一下它的优点:
首先我们自定定义一个View放在ViewHolder中:
public class FloorView extends ImageView {
//这里如果数组大于0可以放大FloorView的内存占用。
private Bitmap[] bitmaps=new Bitmap[0];
public FloorView(Context context) {
super(context);
init();
}
public FloorView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public FloorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
for (int i = 0; i < bitmaps.length; i++) {
bitmaps[i]= BitmapFactory.decodeResource(getResources(),R.drawable.pic1);
}
Log.e("lmtlmt","init");
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Log.e("lmtlmt","onAttachedToWindow");
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.e("lmtlmt","onDetachedFromWindow");
}
}
ViewPager的Adapter代码如下:
public class MyPagerAdapter extends PagerAdapter{
private Context context;
private SparseArray<RecyclerView> sparseArray= new SparseArray<>();
private RecyclerView.RecycledViewPool pool;
MyPagerAdapter(Context context){
this.context=context;
}
@Override
public int getCount() {
return 20;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
RecyclerView recyclerView;
if (sparseArray.get(position)==null){
recyclerView=new RecyclerView(context);
if (pool==null){
pool=recyclerView.getRecycledViewPool();
pool.setMaxRecycledViews(0,8);
}
else {
recyclerView.setRecycledViewPool(pool);
}
recyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(context);
linearLayoutManager.setRecycleChildrenOnDetach(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(new ListAdapter(context));
sparseArray.put(position,recyclerView);
}
else {
recyclerView=sparseArray.get(position);
}
container.addView(recyclerView);
return recyclerView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
RecyclerView.RecycledViewPool pool相对于adapter是一个单例,
所有RecyclerView使用同一个pool。
每个tab滑动一下,然后切换tab再滑动,直到最后一个tab。
我们会发现在左右滑动viewpager时候不会CreateViewHolder了。
我们直接看堆的情况:
手动GC后,FloorView只有16个实例,不是很多。
接下来我们注释掉pool相关的代码,同样的滑动操作结束后
手动GC后,FloorView只有160个实例。其实也就是有160个viewHolder的实例。
我们使用RecycledViewPool,
1.节约了内存
2.减少了CreateViewHolder的资源开销。
3.自然更加流畅
代码地址:
https://github.com/AndroidMsky/RecyclerViewPool
欢迎关注我的博客,和Github。