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

android Universal-Image-Loader oom:关于bitmap的优化及其他优化

2016-01-29 13:55 381 查看

概述

今天朋友使用Universal-Image-Loader的ImageLoader加载图片时遇到oom的问题,然后我按照网上的方法试了下,都没作用。最后不得不自己定位解决……

问题描述

用一个gridview显示网络图片

GridView可以下拉刷新(更新最新的20条),上拉加载(加载20条);


当显示100张左右图片的时候,log就会打印出oom异常。

最后定位到是:position相同,但getView()会触发多次(相信很多人都遇到过)。而position相同,获取到网络上图片的bitmap却不是同一对象

加载图片的代码片段

/*
*imageUrl 图片地址
*imageView 放图片的ImageView实例
*options 第三方框架的DisplayImageOptions
*SimpleImageLoadingListener 图片加载的监听
*/
ImageLoader.getInstance().displayImage(imageUrl, imageView, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
}

@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}

@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
//getView()调用多次,position相同,但返回的loadedImage对象却是多个实例。
}
});


打印的log

01-29 09:11:26.760    ---> android.graphics.Bitmap@2f414b76;position=1
01-29 09:11:26.830    ---> android.graphics.Bitmap@3057b014;position=0
01-29 09:11:26.830    ---> android.graphics.Bitmap@107440bd;position=3
01-29 09:11:26.890    ---> android.graphics.Bitmap@21702bfe;position=6
01-29 09:11:26.950    ---> android.graphics.Bitmap@1810edac;position=9
01-29 09:11:26.950    ---> android.graphics.Bitmap@26a7ca75;position=0
01-29 09:11:26.960    ---> android.graphics.Bitmap@209f0a0a;position=8
01-29 09:11:26.960    ---> android.graphics.Bitmap@2682827b;position=7
01-29 09:11:27.000    ---> android.graphics.Bitmap@caccb57;position=0
01-29 09:11:27.000    ---> android.graphics.Bitmap@27d14644;position=5
01-29 09:11:27.000    ---> android.graphics.Bitmap@141bd32d;position=4
01-29 09:11:27.050    ---> android.graphics.Bitmap@2abe82b0;position=2
01-29 09:11:27.050    ---> android.graphics.Bitmap@30f7529;position=0
01-29 09:11:27.110    ---> android.graphics.Bitmap@179fce4f;po
4000
sition=0
01-29 09:13:05.350    ---> android.graphics.Bitmap@1a5536a4;position=12
01-29 09:13:05.350    ---> android.graphics.Bitmap@13c66c0d;position=0
01-29 09:13:05.350    ---> android.graphics.Bitmap@3f7627c2;position=15
01-29 09:13:05.350    ---> android.graphics.Bitmap@77839d3;position=13
01-29 09:13:05.420    ---> android.graphics.Bitmap@1874ed1a;position=18
01-29 09:13:05.420    ---> android.graphics.Bitmap@623104b;position=19
01-29 09:13:05.420    ---> android.graphics.Bitmap@30e6fa28;position=16
01-29 09:13:05.420    ---> android.graphics.Bitmap@1580e341;position=17
01-29 09:13:05.420    ---> android.graphics.Bitmap@3264c0e6;position=14
01-29 09:13:05.420    ---> android.graphics.Bitmap@3f906627;position=11
01-29 09:13:05.420    ---> android.graphics.Bitmap@38c590d4;position=10
01-29 09:13:05.420    ---> android.graphics.Bitmap@3637727d;position=9
01-29 09:13:05.420    ---> android.graphics.Bitmap@42c0572;position=8
01-29 09:13:05.420    ---> android.graphics.Bitmap@18933dc3;position=0
01-29 09:13:05.420    ---> android.graphics.Bitmap@1b54e640;position=3
01-29 09:13:05.420    ---> android.graphics.Bitmap@16cdb979;position=7
01-29 09:13:05.480    ---> android.graphics.Bitmap@ce13d58;position=0
01-29 09:13:05.480    ---> android.graphics.Bitmap@26a81eb1;position=4
01-29 09:13:05.480    ---> android.graphics.Bitmap@1cd52f96;position=5
01-29 09:13:05.480    ---> android.graphics.Bitmap@1f492717;position=6
01-29 09:13:05.480    ---> android.graphics.Bitmap@2ed8d704;position=2
01-29 09:13:05.480    ---> android.graphics.Bitmap@14eef4ed;position=1


解决方案

gridview->adapter->getView()->使用框架bitmap优化代码片段

public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
addRecycleBitmap(position,loadedImage);//复用bitmap对象
}


addRecycleBitmap()方法代码

private HashMap<Integer,Bitmap> recycleBitmaps = new private HashMap<Integer,Bitmap>();
Bitmap localBitmap= null;
/**
*将不再使用的bitmap recycle掉
*/
public void addRecycleBitmap(int position,Bitmap bitmap) {
//注意这里不能优化position=0的,否则不显示第一个。原因还要再仔细瞅瞅
if(recycleBitmaps.containsKey(position)&&position!=0){//第1位已经有bitmap了
localBitmap = recycleBitmaps.get(position);
if(null != localBitmap&&localBitmap != bitmap&&!localBitmap.isRecycled()){
localBitmap.recycle();
localBitmap = null;
}
}
recycleBitmaps.put(position,bitmap);
}


到此,就能解决掉这个问题了。当然代码方面还可以优化,只是说这个问题的解决方案是这样的……只是还有几点疑惑

疑惑

为什么getView()的position=0,bitmap没法recycle

同一个position=0为什么执行了多次(知道是因为重新绘制了界面,但是具体代码源码没浏览到)

bitmap所在的activity销毁了,bitmap对象被回收了?

如果图片不停的增加,到1000张甚至更多,这肯定会撑爆。所以最终解决方案就是类似getView的复用

网上一些关于解决ImageLoader OOM的建议

参考博客

1. 减少线程池中线程的个数,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推荐配置1-5

2. 在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565,因为默认是ARGB_8888, 使用RGB_565会比使用ARGB_8888少消耗2倍的内存

3. 在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(new WeakMemoryCache()) 或者不使用内存缓存

4. 在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 优化 oom 图片