用户反馈页面中用到了gridview批量上传图片,发现有内存泄漏,也没在网上找到关于gridview图片回收的方法,只有自己慢慢摸索,android studio导了一个又一个hprof,用MAT挨个分析,只要还存在图片类型对象又另外想办法,最后终于找到了回收的方法。
先看看代码:
mGridView=(GridView) findViewById(R.id.gridview);
mGridViewDatas = new ArrayList<>();
Bitmap addBitmap = Utils.getInstance().readBitmap(getApplicationContext(), R.drawable.add_pic);
mGridViewDatas.add(0, addBitmap);
mGridViewAdapter = new GridViewAdapter(getApplication(), mGridViewDatas, MAX_UPLOAD_PIC);
mGridView.setAdapter(mGridViewAdapter);
mGridViewDatas 是用来保存bitmap的list,与gridview控件通过adapter相连。一开始在avtivity的ondestory是只是mGridView = null,用MAT分析内存的情况是:
用神器GIMP打开Bitmap就能看到是gridview中图片没有回收,查看引用关系:
发现是由于mGridViewDatas 还持有图片的引用,于是在onDestory中加了一行:
mGridViewDatas.clear();
再次运行抓取hprof,得到如下结果:
对象变了,但仍然没有释放,查看引用关系:
看到一个pictureLayout对象,这是包含gridview的layout,尝试过
pictureLayout.removeAllViews();
没用,后来又尝试从gridview入手:
mGridView.removeAllViews();
查看注释才发现gridview不支持这个方法,最后换成这样:
mGridView.removeAllViewsInLayout();
运行app,抓hprof分析,得到结果:
没有bitmap,也没有imageview,gridview资源被回收。
总结
gridview在回收的时候要清除数据对象和view系统才能回收图片资源:
//消除内存泄漏
mGridView.removeAllViewsInLayout();
mGridView = null;
mGridViewDatas.clear();
网上没有找到现成的方法只有自己慢慢琢磨,正好再熟悉下MAT。