android viewpager内存溢出,Android 导航(介绍)页面ViewPager内存溢出解决方法

现在基本每个Android App都会标配一个启动介绍的页面,或做产品介绍,或做app功能展示,既然起导航界面,基本思路就是用ViewPager实现。(图片引自UI中国一设计师的设计图片)

20180919144844291962.png

正好这几天在做这个导航界面,我的测试手机是魅族MX3,做完之后测试还行,没有明显卡顿的现象,但是当我把debug的apk装到米3和魅蓝上时,程序运行到这个导航界面会马上crash掉,偶尔没有crash也会出现明显的卡顿现象,体验效果非常差。

打开Android Studio的内存管理器查看运行时分配内存,当时我就蒙逼了,180+M左右,就这个导航界面用了180M,还做什么安卓。。。

改了很多地方,效果依旧不明显,查阅资料有说另外写一个Adapter继承自PagerAdapter,方法如下:

1 class GuideAdapter extendsPagerAdapter{2 private Listviews;3 private final LinkedList recyleBin=new LinkedList<>();4 public GuideAdapter(Listviews){5 this.views=views;6 }7 @Override8 public intgetCount() {9 returnviews.size();10 }11 @Override12 public booleanisViewFromObject(View view, Object object) {13 return view==object;14 }15 @Override16 public void destroyItem(ViewGroup container, intposition, Object object) {17 container.removeView(views.get(position));18 }19 @Override20 public intgetItemPosition(Object object) {21 return super.getItemPosition(object);22 }23 @Override24 public Object instantiateItem(ViewGroup container, intposition) {25 //在此设置背景图片,提高加载速度,解决OOM问题

26 View view;27 int count=getCount();28 if(!recyleBin.isEmpty()) {29 view=recyleBin.pop();30 }else{31 view=views.get(position);32 ViewGroup.LayoutParams params = newViewGroup.LayoutParams(33 ViewGroup.LayoutParams.MATCH_PARENT,34 ViewGroup.LayoutParams.MATCH_PARENT);35 view.setBackgroundResource(images[position %count]);36 view.setLayoutParams(params);37 }38 container.addView(view,0);39 returnviews.get(position);40 }41 }

初始化的时候让viewpager的adapter为上面的自定义的adapter即可,基本代码如下:

1 privateViewPager mViewPager;2 privateGuideAdapter mGuideAdapter;3 private int[] images;//显示介绍的图片的id值

4 private ArrayListviews;5 private ImageView[] indicator=null;//下面的导航指示器,此处不做过多介绍,可忽略

6

7 ...8 ...9 //控件初始化业务

10 mViewPager=(ViewPager)findViewById(R.id.viewpager);11 views=new ArrayList<>();12 //此处放入五张介绍的图片的id值

13 images=new int[]{R.drawable.bg_1,R.drawable.bg_2,R.drawable.bg_3,R.drawable.bg_4,R.drawable.bg_5}14 //adapter实例化

15 mGuideAdapter=newGuideAdapter(views);16 //循环加入图片的业务

17 for(int i=0;i

22 views.add(mImageView);//添加入动态数组里面,此处的ImageView里面均为没有背景的imageview23 //for循环内还有指示器的添加,因不在讨论问题的重点内,忽略业务代码

24 }25 //为mViewPager绑定适配器

26 mViewPager.setAdapter(mGuideAdapter);27 mViewPager.setCurrentItem(0);28 mViewPager.setOffscreenPageLimit(1);29 mViewPager.setOnPageChangeListener(this);30 ...31 ...

基本的思路就是让加载viewpager过多的没有显示的图片在自定义的Adapter的destroyItem里面销毁释放内存,防止造成OOM或者内存溢出crash的问题,这种方法每次加载viewpager的时候只会加载当前一页和前后两页共三页,所以内存占用不会很高。

但是,但是,问题来了。。。重新编写之后测试发现:te me还是占用160M+内存,当时我就傻了。。。怎么不见效果呢。。。于是好长时间都在查资料,找问题,debug。。。

然而,半天过去了。。。

我还是没找到问题到底出在哪里。。。

后来,导师和我说看一下你的图片多少大,我说100k的样子,然后他看了一下,说让我把所有图片拖到PS里面转成PNG再导出来(之前一直都是JPG)。于是照做了,顺便看了一眼新导出的图片大小,看了一下都比JPG的要大,于是半信半疑的替换资源,重新编译运行后。终于惊喜的发现内存占用降到40-60M之间了。。。原来是图片格式的问题,欸,搞了半天头都大了,原来是这么简单的问题。。。

这也横向提示我们以后Android编程里面的资源最好不要用JPG格式的,下载类的图片资源也是,因为32位的PNG颜色过渡平滑且支持透明,JPG是像素化压缩过的图片,质量已经下降了,PNG的压缩算法解压快很多,JPG的话可以有很高的压缩比(当然会有损失),所以综合考虑还是用PNG比较好(特殊需求除外)。

在此也感谢我的导师,在我开发当中教我好多,第一次写博客,即当作自己的记事本,日后还能看看,也希望能解决大家相似的问题,第一次写,一定会有表达不到位,表述不清楚的地方,希望留下你的评论和建议,我也可以改正,提高自己。

(本博客属于本人原创,本人CSDN文章原创地址:http://blog.csdn.net/wiz_chen/article/details/45119783)

原文:http://www.cnblogs.com/wiz-Chen/p/4495245.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值