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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章