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);    }

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

疑惑

  1. 为什么getView()的position=0,bitmap没法recycle
  2. 同一个position=0为什么执行了多次(知道是因为重新绘制了界面,但是具体代码源码没浏览到)
  3. bitmap所在的activity销毁了,bitmap对象被回收了?
  4. 如果图片不停的增加,到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)

0 0
原创粉丝点击