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

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

正好这几天在做这个导航界面,我的测试手机是魅族MX3,做完之后测试还行,没有明显卡顿的现象,但是当我把debug的apk装到米3和魅蓝上时,程序运行到这个导航界面会马上crash掉,偶尔没有crash也会出现明显的卡顿现象,体验效果非常差。 
打开Android Studio的内存管理器查看运行时分配内存,当时我就蒙逼了,180+M左右,就这个导航界面用了180M,还做什么安卓。。。 
改了很多地方,效果依旧不明显,查阅资料有说另外写一个Adapter继承自PagerAdapter,方法如下:

 1 class GuideAdapter extends PagerAdapter{
 2         private List<View> views;
 3         private final LinkedList<View> recyleBin=new LinkedList<>();
 4         public GuideAdapter(List<View>views){
 5             this.views=views;
 6         }
 7         @Override
 8         public int getCount() {
 9             return views.size();
10         }
11         @Override
12         public boolean isViewFromObject(View view, Object object) {
13             return view==object;
14         }
15         @Override
16         public void destroyItem(ViewGroup container, int position, Object object) {
17             container.removeView(views.get(position));
18         }
19         @Override
20         public int getItemPosition(Object object) {
21             return super.getItemPosition(object);
22         }
23         @Override
24         public Object instantiateItem(ViewGroup container, int position) {
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 = new ViewGroup.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             return views.get(position);
40         }
41 }

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

 1 private ViewPager mViewPager;
 2     private GuideAdapter mGuideAdapter;
 3     private int[] images;//显示介绍的图片的id值
 4     private ArrayList<View>views;
 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=new GuideAdapter(views);
16     //循环加入图片的业务
17     for(int i=0;i<images.length;i++){
18         ImageView mImageView=new ImageView(this);
19     //下面这一步会导致OOM,所以添加backgroundResource的步骤在自定义的adapter的
20     //instantiateItem方法里面实现,此处已注释
21     //mImageView.setBackgroundResource(images[i]);
22     views.add(mImageView);//添加入动态数组里面,此处的ImageView里面均为没有背景的imageview
23     //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)

时间: 2024-10-27 05:55:00

Android 导航(介绍)页面ViewPager内存溢出解决方法的相关文章

Webloginc 内存溢出解决方法

  Webloginc 内存溢出解决方法  : javax.servlet.ServletException: java.lang.OutOfMemoryError: PermGen space 解决方法: 1.在base_domain 域下找到startWebLogic.bat 文件,然后打开编辑, 2.然后加入以下的代码 JAVA_OPTS='-Xms512m -Xmx2048m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=25

MyEclipse内存溢出解决方法

MyEclipse内存溢出解决方法 1.修改eclipse.ini 在Myeclipse安装目录下G:\MyEclipse8.5\Genuitec\MyEclipse 8.5有一个myeclipse.ini配置文件,设置如下: -vmargs-Xmx512m-XX:MaxPermSize=256m-XX:ReservedCodeCacheSize=64m 2.设置Default VM Arguments 在myEclipse中,打开Windows-> Preferences->Java->

weblogic10内存溢出解决方法

在开发过程中经常会遇到weblogic内存溢出问题,用下面的办法解决了. 找到domain/bin下的setDomainEnv.cmd文件,里面可以找到以下四行代码,将值该打一倍,重启服务. set MEM_PERM_SIZE_64BIT=-XX:PermSize=128m set MEM_PERM_SIZE_32BIT=-XX:PermSize=48m set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=256m set MEM_MAX_PERM_SIZE_

JMeter学习(二十八)内存溢出解决方法

使用jmeter进行压力测试时遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jmeter.bat中增加了JVM_ARGS="-Xmx2048m -Xms2048m -Xmn256m -XX:PermSize=128m -Xss256k",但结果运行时间增加了,但最终还是报内存溢出,百度后按照网友的建议更改了如下设置后jmeter就没有再卡了: 1.windows环境下,修改jmeter.bat: set HEAP=-Xms256m -Xmx256m

【转】JMeter学习(二十八)内存溢出解决方法

使用jmeter进行压力测试时遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jmeter.bat中增加了JVM_ARGS="-Xmx2048m -Xms2048m -Xmn256m -XX:PermSize=128m -Xss256k",但结果运行时间增加了,但最终还是报内存溢出,百度后按照网友的建议更改了如下设置后jmeter就没有再卡了: 1.windows环境下,修改jmeter.bat: set HEAP=-Xms256m -Xmx256m

maven内存溢出解决方法

maven内存溢出(InvocationTargetException: PermGen space) 解决方案:maven脚本:mvn.bat文件 @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 后加入一行set MAVEN_OPTS= -Xms256m -Xmx512m

weblogic内存溢出解决方法以及无密码直接启动weblogic

找到D:\weblogic10.3.6\wlserver_10.3\common\bin,编辑commEnv.cmd文件: set JAVA_VM=-jrockit set MEM_ARGS=-Xms1024m -Xmx2048m set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none goto continue -Xms:内存初始值 -Xmx:内存最大值(不要超过内存的 80%) 2.找到D:\weblogic10.3.6\user_projects\dom

Exception in thread &quot;main&quot; java.lang.OutOfMemoryError: Java heap space(Java堆空间内存溢出)解决方法

http://hi.baidu.com/619195553dream/blog/item/be9f12adc1b5a3e71f17a2e9.html问题描述Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 解决方案[转] 一直都知道可以设置jvm heap大小,一直用eclipse写/调试java程序.一直用命令行or console加参数跑程序.现象:在eclipse的配置文件eclipse.

nodejs内存溢出解决方法

解决方案一:通过 package.json 中的 "pro" 加大内存 解决方案二:使用 increase-memory-limit 插件,增加node服务器内存限制 "dependencies":{ "increase-memory-limit":"^1.6.0" } "script":{ "fix-memory-limit":"cross-env LIMIT=8000 in