Android 导航(介绍)页面ViewPager内存溢出解决方法
2015-04-19 00:11
597 查看
现在基本每个Android App都会标配一个启动介绍的页面,或做产品介绍,或做app功能展示,既然起导航界面,基本思路就是用ViewPager实现。(图片引自UI中国一设计师的设计图片)
正好这几天在做这个导航界面,我的测试手机是魅族MX3,做完之后测试还行,没有明显卡顿的现象,但是当我把debug的apk装到米3和魅蓝上时,程序运行到这个导航界面会马上crash掉,偶尔没有crash也会出现明显的卡顿现象,体验效果非常差。
打开Android Studio的内存管理器查看运行时分配内存,当时我就蒙逼了,180+M左右,就这个导航界面用了180M,还做什么安卓。。。
改了很多地方,效果依旧不明显,查阅资料有说另外写一个Adapter继承自PagerAdapter,方法如下:
初始化的时候让viewpager的adapter为上面的自定义的adapter即可,基本代码如下:
基本的思路就是让加载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比较好(特殊需求除外)。
在此也感谢我的导师,在我开发当中教我好多,第一次写博客,即当作自己的记事本,日后还能看看,也希望能解决大家相似的问题,第一次写,一定会有表达不到位,表述不清楚的地方,希望留下你的评论和建议,我也可以改正,提高自己。
正好这几天在做这个导航界面,我的测试手机是魅族MX3,做完之后测试还行,没有明显卡顿的现象,但是当我把debug的apk装到米3和魅蓝上时,程序运行到这个导航界面会马上crash掉,偶尔没有crash也会出现明显的卡顿现象,体验效果非常差。
打开Android Studio的内存管理器查看运行时分配内存,当时我就蒙逼了,180+M左右,就这个导航界面用了180M,还做什么安卓。。。
改了很多地方,效果依旧不明显,查阅资料有说另外写一个Adapter继承自PagerAdapter,方法如下:
class GuideAdapter extends PagerAdapter{ private List<View> views; private final LinkedList<View> recyleBin=new LinkedList<>(); public GuideAdapter(List<View>views){ this.views=views; } @Override public int getCount() { return views.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view==object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(views.get(position)); } @Override public int getItemPosition(Object object) { return super.getItemPosition(object); } @Override public Object instantiateItem(ViewGroup container, int position) { //在此设置背景图片,提高加载速度,解决OOM问题 View view; int count=getCount(); if(!recyleBin.isEmpty()) { view=recyleBin.pop(); }else { view=views.get(position); ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); view.setBackgroundResource(images[position % count]); view.setLayoutParams(params); } container.addView(view,0); return views.get(position); } }
初始化的时候让viewpager的adapter为上面的自定义的adapter即可,基本代码如下:
private ViewPager mViewPager; private GuideAdapter mGuideAdapter; private int[] images;//显示介绍的图片的id值 private ArrayList<View>views; private ImageView[] indicator=null;//下面的导航指示器,此处不做过多介绍,可忽略 ... ... //控件初始化业务 mViewPager=(ViewPager)findViewById(R.id.viewpager); views=new ArrayList<>(); //此处放入五张介绍的图片的id值 images=new int[]{R.drawable.bg_1,R.drawable.bg_2,R.drawable.bg_3,R.drawable.bg_4,R.drawable.bg_5} //adapter实例化 mGuideAdapter=new GuideAdapter(views); //循环加入图片的业务 for(int i=0;i<images.length;i++){ ImageView mImageView=new ImageView(this); //下面这一步会导致OOM,所以添加backgroundResource的步骤在自定义的adapter的 //instantiateItem方法里面实现,此处已注释 //mImageView.setBackgroundResource(images[i]); views.add(mImageView);//添加入动态数组里面,此处的ImageView里面均为没有背景的imageview //for循环内还有指示器的添加,因不在讨论问题的重点内,忽略业务代码 } //为mViewPager绑定适配器 mViewPager.setAdapter(mGuideAdapter); mViewPager.setCurrentItem(0); mViewPager.setOffscreenPageLimit(1); mViewPager.setOnPageChangeListener(this); ... ...
基本的思路就是让加载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比较好(特殊需求除外)。
在此也感谢我的导师,在我开发当中教我好多,第一次写博客,即当作自己的记事本,日后还能看看,也希望能解决大家相似的问题,第一次写,一定会有表达不到位,表述不清楚的地方,希望留下你的评论和建议,我也可以改正,提高自己。
相关文章推荐
- android 解决ViewPager加载大量图片内存溢出问题
- android 解决ViewPager加载大量图片内存溢出问题
- Android ViewPager多页面滑动切换以及底部滑动导航
- Android 解决ViewPager设置高度为wrap_content无效的方法 MyViewPager
- Android解决ViewPager页面滑动空白bug和图片点击bug
- [置顶] Android开发之viewpager导报错误解决方法:错误代码 Caused by: java.lang.ClassNotFoundException: Didn't find class
- android ViewPager在拖拽到左边和右边的时候,禁止显示黄色或者蓝色的渐变图片的解决方法
- Android新特性页面之ViewPager拖拽到最后一页再拖拽打开其他Activity(三种方法)
- android中通过添加view使用ViewPager出现的问题及解决方法
- Android 逐帧动画AnimationDrawable 内存溢出的一个解决方法
- Android TabLayout、ViewPager实现顶部和底部Tab导航 点击滑动切换Tab页面
- android之TabLayout实现PagerSlidingTabStrip,ViewpagerIndicator之类的效果滑动页面导航效果(类似网易新闻)
- Android解决ViewPager页面滑动空白bug和图片点击bug
- Android加载图片内存溢出问题解决方法
- Android使用帧动画内存溢出解决方法
- Android中解决ListView嵌套Viewpager时,滑动事件冲突的方法
- Android报错ViewPager: Can't Change Tag of Fragment的解决方法
- Android ViewPager向导页面制作方法
- Android利用ViewPager实现图片浏览,解决内存问题
- Android通过Chrome Inspect调试WebView的H5 App出现空白页面的解决方法(不需要FQ)