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

概述

       今天朋友使用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;position=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);
    }

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

疑惑

  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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值