项目中为解决Android out of memeory问题做出的尝试

在项目中要使用几十张图片,以及背景,产生了out of memory异常.

 

 Bitmap bitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), gi.getBitMapResoureceId(), mOptions));

 

因为大量使用图片而且切换屏幕时或回到前台时重复生成Bitmap ,导致内存溢出。

 

专门针对out of memory进行了调查。

问题点:

 

a.使用大量图片,耗用内存和cup

b.横竖屏切换或者activity回到前台时重复的调用了一些代码,例如读取数据库,重复生成一些对象

c.由于组件的背景图片多,在频繁横竖屏切换时重新加载xml会一时间占用大量内存

 

方法:

1.提取重复性的代码,就是能一次在onCreate()中做好的东西,不要再onResume()和onConfigurationChanged()中重复出现,这个要考虑业务和逻辑的东西。

但是组件和Layout还是要在onConfigurationChanged()重新加载的(我们使用了android:configChanges="touchscreen|keyboardHidden|orientation",所以横竖屏切换时只调用onConfigurationChanged()方法)。

2.将app的背景图片和button的背景及src从xml中提取出来,在代码中设置为成员变量,一次性读入不再重复读取

例如:

xml中:

android:background="@drawable/bg"

android:src="@drawable/water"

 Java代码中:

private Drawable mBgDrawable = getResources().getDrawable(R.drawable.bg);

 

private Drawable mWaterDrawable = getResources().getDrawable(R.drawable.waterbg); 

RelativeLayout mMainLayout = (RelativeLayout) findViewById(R.id.main);

 

ImageButton mBtnWater = (ImageButton ) findViewById(R.id.waterbyn);

mMainLayout.setBackgroundDrawable(mBgDrawable );

 

mBtnWater .setImageDrawable(mWaterDrawable );

ImageButton 设置时也可以是setBackgroundDrawable那这样就和xml中的background一个效果了。

 

后来又把这些成员变量做出static的,是为了提高效率。

 

但后来发现了问题。就是网上很多的关于Drawable会使用setCallback保留对组件(ImageButton )的引用,而组件又会保留对activity的引用,这样activity上的计数器不会0,虚拟机也不能回收已经不用的activity对象,再次引发内存溢出。

setBackgroundDrawable:

 这里面的d.setCallback(this)可能会导致保留对组件的引用。当重新调用setBackgroundDrawable时,Drawable调用mBGDrawable.setCallback(null)先将原来的引用设置为null。

 

回到我的项目,我们在切换横竖屏时并没有重新生成activity,也没有需要销毁的activity,而且最初我们没有设置为static,那么这些成员变量的生命周期和activity是相同的,不会引发上述问题。(理论推测)我们目前的做法是在onConfigurationChanged()中增加了这么句话:

mWaterDrawable .setCallback(null)做个双保险。

 

那当将Drawable的变量设置为static后,应该在onDestroy中也调用mWaterDrawable .setCallback(null),保证activity可以被正常回收。

 

继续跟进中……

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值