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 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了。
我们直接看堆的情况:
RecycledViewPool的使用和堆内存分析_第1张图片
手动GC后,FloorView只有16个实例,不是很多。

接下来我们注释掉pool相关的代码,同样的滑动操作结束后
RecycledViewPool的使用和堆内存分析_第2张图片
手动GC后,FloorView只有160个实例。其实也就是有160个viewHolder的实例。

我们使用RecycledViewPool,
1.节约了内存
2.减少了CreateViewHolder的资源开销。
3.自然更加流畅

代码地址:
https://github.com/AndroidMsky/RecyclerViewPool

欢迎关注我的博客,和Github。

你可能感兴趣的:(安卓框架搭建,安卓基础技能,安卓视图控件技巧篇)