使用ViewPager时,发生内存溢出OOM问题

今天在制作应用某个功能的引导页时,使用了ViewPager进行页面切换,每个页面就放了一个ImageView,使用背景图来进行展示,由于多图(11张)的原因,导致了OOM问题,这里总结一下。

代码如下:

public class GuideActivity extends Activity implements OnPageChangeListener{
	private ViewPager viewPager;
	private GuideAdapter adapter;
	private LinearLayout dotContain;
	private Button btnSure;
	private List<View> mViews=new ArrayList<View>();
	private int[] mResIds=new int[]{
			R.drawable.step01,
			R.drawable.step02,
			R.drawable.step03,
			R.drawable.step04,
			R.drawable.step05,
			R.drawable.step06,
			R.drawable.step07,
			R.drawable.step08,
			R.drawable.step09,
			R.drawable.step10,
			R.drawable.step11
			};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_guide);
		initViews();
		initDatas();
	}
	protected void initViews() {
		viewPager=(ViewPager) findViewById(R.id.vp_guide);
		dotContain=(LinearLayout) findViewById(R.id.layout_dot_contain);
		btnSure=(Button) findViewById(R.id.btn_sure);

		adapter=new GuideAdapter(mViews);
	}

	protected void initDatas() {

		for (int i = 0; i < mResIds.length; i++) {
			ImageView img=new ImageView(this);
			//延迟设置图片,在PagerAdapter内设置,解决OOM问题
			/*ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
	                ViewGroup.LayoutParams.MATCH_PARENT,
	                ViewGroup.LayoutParams.MATCH_PARENT);
			img.setBackgroundResource(mResIds[i]);
			img.setLayoutParams(params);*/
			mViews.add(img);
		}
		viewPager.setAdapter(adapter);
		viewPager.setOnPageChangeListener(this);
		viewPager.setCurrentItem(0);
		viewPager.setOffscreenPageLimit(1);
		dotContain.getChildAt(0).setSelected(true);
	}
	/**
	 *
	 * 2014-12-19 上午10:56:19
	 * @param position
	 * @TODO 改变底部图标状态
	 */
	private void chageDotState(final int position){
		int count=dotContain.getChildCount();
		for (int i = 0; i < count; i++) {
			View view=dotContain.getChildAt(i);
			if(position%count==i){
				view.setSelected(true);
			}else{
				view.setSelected(false);
			}
		}
	}
	/**
	 *
	 * @Create_date 2014-12-19 上午11:09:48
	 * @TODO 适配器
	 */
	class GuideAdapter extends PagerAdapter{
		private List<View> views;

		public GuideAdapter(List<View> views) {
			this.views = views;
		}

		@Override
		public int getCount() {
			return views.size();
		}

		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0==arg1;
		}

		@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=views.get(position);
			int count=getCount();
			ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
	                ViewGroup.LayoutParams.MATCH_PARENT,
	                ViewGroup.LayoutParams.MATCH_PARENT);
			view.setBackgroundResource(mResIds[position%count]);
			view.setLayoutParams(params);
			container.addView(view,0);
			return views.get(position);
		}
	}

	@Override
	public void onPageScrollStateChanged(int arg0) {

	}
	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {

	}
	@Override
	public void onPageSelected(int arg0) {
		if(arg0<adapter.getCount()-1){
			dotContain.setVisibility(View.VISIBLE);
			btnSure.setVisibility(View.GONE);
			chageDotState(arg0);
		}else{
			dotContain.setVisibility(View.GONE);
			btnSure.setVisibility(View.VISIBLE);
		}
	}
}

代码中已经进行了说明。一开始,使用了一个for循环,将所有的ImageView设置了背景并添加到List<View>中,这样导致,一点进这个界面时,有点卡顿,并且有时还会出现OOM问题。

解决办法就是:在for循环内只将ImageView对象添加到List<View>中,并不对其设置背景资源,将该步骤延迟到PagerAdapter$instantiateItem()中再进行设置。

说明:页面过多会报OOM的原因是,当ImageView在调用setBackgroundResource时,底层会调用BitmapFactory.decodeResource进行解码,而这个过程是耗时的,也很容易就OOM了,因此在for循环内进行多图设置的话就导致卡顿甚至OOM了。

时间: 2024-10-11 09:36:41

使用ViewPager时,发生内存溢出OOM问题的相关文章

viewPager--viewpager时,发生内存溢出OOM问题

两个问题:1.如果图片达到500kb每张,你这个划屏会有顿卡:2.快速滑动有出现0.几秒的白屏.图片越大,顿卡越明显. 回复parcool:500kb的背景算大的了,如果是想做图片墙,viewpager不适合,可以使用开源的图片墙工具,内存+硬盘缓存 还有哦,你这个图片根本没有手动回收,依然会OOM! 今天在制作应用某个功能的引导页时,使用了ViewPager进行页面切换,每个页面就放了一个ImageView,使用背景图来进行展示,由于多图(11张)的原因,导致了OOM问题,这里总结一下. 代码

内存溢出(Oom)和内存泄露(Memory leak)

内存溢出(Oom):运行内存大于可用内存的情况.比如申请了一个integer空间,结果存放下了只有long才能存放的数据 内存泄露(Memory leak):程序员忘记释放已用内存的情况,是内存管理较为常见的现象 以发生的方式来分类,内存泄漏可以分为4类: 1. 常发性内存泄漏.发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏. 2. 偶发性内存泄漏.发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生.常发性和偶发性是相对的.对于特定的环境,偶发性的也许就变成了常发性

如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码

程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习<深入理解java虚拟机-JVM高级特性与最佳实践>这本书,终于初步了解了一下java虚拟机的内存模型.本文通过写出使jvm发生内存溢出异常的代码来对自己的学习结果进行总结,同时也提醒自己以后写代码时候不要再跳进这个坑啦. java的内存管理是由java虚拟机自动进行管理的,并不需要程序员过多的手动干预

内存溢出OOM

1, OutOfMemoryError异常 除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能, javaHeap 溢出 一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常. 出现这种异常,一般手段是先通过内

java常见内存溢出(OOM)

jvm内存区域 程序计数器一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器. java栈与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同.通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址) 栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常:如果虚拟机栈可以动态扩展(大部分虚拟机都可动态扩展),当扩展

强如 Disruptor 也发生内存溢出?

前言 OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界.空指针等)来说这类问题是很难定位和解决的. 本文以最近碰到的一次线上内存溢出的定位.解决问题的方式展开:希望能对碰到类似问题的同学带来思路和帮助. 主要从表现-->排查-->定位-->解决 四个步骤来分析和解决问题. 表象 最近我们生产上的一个应用不断的爆出内存溢出,并且随着业务量的增长出现的频次越来越高. 该程序的业务逻辑非常简单,就是从 Kafka 中将数据消费下来然后批量的做持久化操作

小编带你进入强如 Disruptor 也发生内存溢出?

前言OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界.空指针等)来说这类问题是很难定位和解决的. 本文以最近碰到的一次线上内存溢出的定位.解决问题的方式展开:希望能对碰到类似问题的同学带来思路和帮助. 主要从表现-->排查-->定位-->解决 四个步骤来分析和解决问题. 表象最近我们生产上的一个应用不断的爆出内存溢出,并且随着业务量的增长出现的频次越来越高. 该程序的业务逻辑非常简单,就是从 Kafka 中将数据消费下来然后批量的做持久化操作.

bitmap 内存溢出OOM的解决办法分享

昨天遇到这个问题就是从一个输入流里调用BitmapFactory.decodeStream(this.getContentResolver().openInputStream(uri))得到一个bitmap报的错.第一次调用都没问题,第二次再次调用就会报上面那个内存溢出的问题.而且有的手机报有的手机不报.研究了半天终于解决.首先分析了下原因,应该是图片占用的内存超过了系统虚拟机可分配的最大限制.不同手机可能分配的最大值不一样.后来找到解决办法主要是设置BitmapFactory.Options.

jenkins 构建部署时tomcat7 内存溢出解决方案

在使用jenkins构建部署时一直出现tomcat7内存溢出 WARNING: Unexpected node monitoring termination: Clock Difference java.lang.OutOfMemoryError: PermGen space 修改TOMCAT_HOME/bin/catalina.bat(Linux下为catalina.sh) “echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: se