您的位置:首页 > 其它

笔记【OOM 和 Bitmap 和 ImageView 的内存管理】

2015-02-26 17:06 330 查看

小标题写些什么好呢

之前项目遇到了大图无法即时回收的情况,还是那句话找点东西看看,顺着UCG社区“UGC社区”相同的尿性,找着了四次元(微次元)的源代码。

琢磨着一看,Heap Size那边回收还成,就看了下代码,还真不错,于是并到自己代码中,写了套小东西。

写在前头的”思路分析”

首先明确我们的需求:一个不会OOM的ImageView异步加载Bitmap。

然后开始说思路:

ImageView载入Bitmap,很多时候大家都会遇到oom的问题。那么这个思路分析就是简单粗暴的解决这问题,代码会放出稍后请见后续连接。

AsyncTask中WeakReference(弱引用)ImageView,先去LRU缓存中拿Bitmap对象,有则返回,无则继续从“本地文件”中拿,拿了仍一份进LRU,再从LRU中拿,如果两者都无,则要去下载图片存为“本地文件”了。

特别注意:如果在加载Bitmap中遇到了OOM(BitmapFactory.decodeXXX相关语句)时,清空LRU缓存中的对象,好让其自己释放之(evictAll()方法)。

try {
bitmap = ImageUtility.readNormalPic(path, width, height);
} catch (OutOfMemoryError ignored) {
KituriApplication.getInstance().getBitmapCache().evictAll();
try {
bitmap = ImageUtility.readNormalPic(path, width, height);
} catch (OutOfMemoryError ignoredToo) {

}
}


代码敲在博客里都变形了……还真不好看- -0

使用LRU缓存

//image memory cache
private LruCache<String, Bitmap> appBitmapCache = null;

public synchronized LruCache<String, Bitmap> getBitmapCache() {
if (appBitmapCache == null) {
buildCache();
}
return appBitmapCache;
}

//初始化方法 分配多大内存才适合本程序的init方式
private void buildCache() {
int memClass = ((ActivityManager) getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();

int cacheSize = Math.max(1024 * 1024 * 8, 1024 * 1024 * memClass / 6);

appBitmapCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {

return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}


以上这些东西,推荐写在“Application”里,LRU嘛,跟着系统来,跟着系统走较为合适,至于LRU用多大,你跟着上面的来就好了,一般这个大小基本够用。

文件缓存 和 自定义AsyncTask

毕竟还是四次元作者自己写的,建议去源代码里看一下,会理解更深刻一些。你复制黏贴拿去用问题也不大,了解上面的思路即可。(推荐)

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