android Universal-Image-Loader oom:关于bitmap的优化及其他优化
来源:互联网 发布:大型网络3d游戏 编辑:程序博客网 时间:2024/06/11 04:37
概述
今天朋友使用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=101-29 09:11:26.830 ---> android.graphics.Bitmap@3057b014;position=001-29 09:11:26.830 ---> android.graphics.Bitmap@107440bd;position=301-29 09:11:26.890 ---> android.graphics.Bitmap@21702bfe;position=601-29 09:11:26.950 ---> android.graphics.Bitmap@1810edac;position=901-29 09:11:26.950 ---> android.graphics.Bitmap@26a7ca75;position=001-29 09:11:26.960 ---> android.graphics.Bitmap@209f0a0a;position=801-29 09:11:26.960 ---> android.graphics.Bitmap@2682827b;position=701-29 09:11:27.000 ---> android.graphics.Bitmap@caccb57;position=001-29 09:11:27.000 ---> android.graphics.Bitmap@27d14644;position=501-29 09:11:27.000 ---> android.graphics.Bitmap@141bd32d;position=401-29 09:11:27.050 ---> android.graphics.Bitmap@2abe82b0;position=201-29 09:11:27.050 ---> android.graphics.Bitmap@30f7529;position=001-29 09:11:27.110 ---> android.graphics.Bitmap@179fce4f;position=001-29 09:13:05.350 ---> android.graphics.Bitmap@1a5536a4;position=1201-29 09:13:05.350 ---> android.graphics.Bitmap@13c66c0d;position=001-29 09:13:05.350 ---> android.graphics.Bitmap@3f7627c2;position=1501-29 09:13:05.350 ---> android.graphics.Bitmap@77839d3;position=1301-29 09:13:05.420 ---> android.graphics.Bitmap@1874ed1a;position=1801-29 09:13:05.420 ---> android.graphics.Bitmap@623104b;position=1901-29 09:13:05.420 ---> android.graphics.Bitmap@30e6fa28;position=1601-29 09:13:05.420 ---> android.graphics.Bitmap@1580e341;position=1701-29 09:13:05.420 ---> android.graphics.Bitmap@3264c0e6;position=1401-29 09:13:05.420 ---> android.graphics.Bitmap@3f906627;position=1101-29 09:13:05.420 ---> android.graphics.Bitmap@38c590d4;position=1001-29 09:13:05.420 ---> android.graphics.Bitmap@3637727d;position=901-29 09:13:05.420 ---> android.graphics.Bitmap@42c0572;position=801-29 09:13:05.420 ---> android.graphics.Bitmap@18933dc3;position=001-29 09:13:05.420 ---> android.graphics.Bitmap@1b54e640;position=301-29 09:13:05.420 ---> android.graphics.Bitmap@16cdb979;position=701-29 09:13:05.480 ---> android.graphics.Bitmap@ce13d58;position=001-29 09:13:05.480 ---> android.graphics.Bitmap@26a81eb1;position=401-29 09:13:05.480 ---> android.graphics.Bitmap@1cd52f96;position=501-29 09:13:05.480 ---> android.graphics.Bitmap@1f492717;position=601-29 09:13:05.480 ---> android.graphics.Bitmap@2ed8d704;position=201-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 Universal-Image-Loader oom:关于bitmap的优化及其他优化
- (源码分析)Android-Universal-Image-Loader (图片异步加载缓存库)对Bitmap的优化处理
- Android-Universal-Image-Loader 使用遇到的oom问题
- 关于Android-Universal-Image-Loader的流程
- Android - RecycleView 使用 Universal-Image-Loader加载优化
- Universal image loader遇到OOM
- Universal-Image-Loader出现oom
- Android Bitmap 防止OOM及其他操作
- Android 优化Bitmap避免OOM
- 安卓上网络图片的处理解决oom------------Universal Image Loader for Android
- universal-image-loader解决OOM(从别处找的资料)
- android-universal-image-loader
- Android-Universal-Image-Loader
- Android-Universal-Image-Loader
- Android-Universal-Image-Loader
- Android-Universal-Image-Loader
- Android Universal Image Loader
- Android-Universal-Image-Loader
- 《2》观察者模式
- iconv用法解读
- perl 微信 获取消息
- Java Code Examples for org.apache.commons.codec.binary.Base64InputStream
- java学习之路
- android Universal-Image-Loader oom:关于bitmap的优化及其他优化
- 大数据量时Mysql的优化要点
- js 方法的动态调用 apply的用法
- iOS [[UIDevice currentDevice] systemName]的返回值
- 初遇Express(小demo)
- Android NDK生成so文件
- 第五章第二节-spring注入属性
- STL_算法_根据第n个元素排序(nth_element)
- [Leetcode]146. LRU Cache @python