您的位置:首页 > 移动开发 > Android开发

android 内存溢出oom错误的一些小见解

2013-08-29 23:00 393 查看
转:http://blog.csdn.net/xuhui_7810/article/details/9493681

我们在代码里调用setBackgroundResource(int resid)来设置一个view控件的背景时,如果图片过大,或者调用setBackgroundResource(int resid)多次时,有可能导致内存溢出.查看代码:

public void setBackgroundResource(int resid) {
if (resid != 0 && resid == mBackgroundResource) {
return;
}

Drawable d= null;
if (resid != 0) {
d = mResources.getDrawable(resid);
}
setBackgroundDrawable(d);

mBackgroundResource = resid;
}

可以发现,背景图片最后设置为了一个Drawable对象.Drawable对象占用的内存分为java层的和底层的两部份.JAVA层的内存,如果在你的view释放时,你的背景图片调用了Drawable的setCallback(null), 即取消你的背景图片在VM里的引用,则JAVA这部份的内存空间,在系统调用GC函数时可以把它回收. 但是在native层的内存,GC是释放不了的.这样就会导致有内存泄漏. 解决这个问题的办法有很多种,下面我来说说最简单的一种:

设置背景时,不要调用setBackgroundResource(int resid),而改用setBackgroundDrawable(Drawable d) 这个函数,这个函数的参数d 用一个BitmapDrawable new出来.上代码:

[java] view plaincopy

Bitmap mBgBitmap = null;

mBgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.unlock_bg);

setBackgroundDrawable(new BitmapDrawable(mBgBitmap));

这样的好处就是,我们可以保留图片的Bitmap引用mBgBitmap,在我们的VIEW释放时,我们显示的调用

[java] view plaincopy

if(mBgBitmap != null && !mBgBitmap.isRecycled())

{

mBgBitmap.recycle();

mBgBitmap = null;

}

这段代码,就可以把native层的内层也给释放掉,这样就可以彻底解决内存泄漏的问题

加上LruCache效果相比更佳

private LruCache mMemoryCache;

@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Get memory class of this device, exceeding this amount will throw an
// OutOfMemory exception.
final int memClass = ((ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();

// Use 1/8th of the available memory for this memory cache.
final int cacheSize = 1024 * 1024 * memClass / 8;

mMemoryCache = new LruCache(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in bytes rather than number of items.
return bitmap.getByteCount();
}
};
...
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}

public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: