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

Android图片加载方案——如何保证图片清晰度同时,最大限度节省内存使用量

2015-09-09 13:55 190 查看
最近做的项目里,需要在主页面加载很多图片。那么就尝尝出现OOM,尝试了多种方法,最后找到一种很不错的办法,极大的节省了内存空间,原先程序运行时的内存占有量大约在120-200左右,又时甚至能达到醉人的250直接OOM掉。修改过后,长期稳定在60-100M之间。所以说优化了接近50%。那么现在我们就来看看,我是怎么做的~~

【一】使用Drawable代替bitmap

经过实际测试发现,Drawable在加载图片的性能上和占用内存上都远小于bitmap。(实验证明,加载同样的1000张图片,drawable可以快速的加载完1000张图片,而bitmap仅仅加载到第8张就OOM了。。。)本人才疏学浅不止其中奥义,也不知道为什么大家都爱用bitmap,也希望有识之士能够告知我一下原因。

详见:http://blog.csdn.net/zhu071011/article/details/48310597

【二】使用decodeStream杜绝decodeResource

同样是经过大量实干中得出的经验。decodeStream的加载方式是调用了非java层面的代码进行操作的,所以效率很高。经过试验,用bitmap去加载1000张图片,使用decodeResource的只能加载到第8张,使用decodeStream的可以加载到566张,可见其效率提升的多么显著。

示例:

public static Bitmap readBitMap(Context context, int resId) {
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inPreferredConfig = Bitmap.Config.ARGB_4444;
    opt.inPurgeable = true;
    opt.inInputShareable = true;
// 获取资源图片
    InputStream is = context.getResources().openRawResource(resId);
    Bitmap bitmap =  BitmapFactory.decodeStream(is, null, opt);
    try {
        if(is != null)
            is.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bitmap;
}


【三】巧用BitmapFactroy.Options进行图像高效压缩

网上铺天盖地的都是推荐使用simplesize来进行图像压缩,然而,我却发现一种更节省内存的方法。依然是使用BitmapFactroy.Options,通过设置图片的显示密度来压缩图片,从而达到减小内存占用量的目的。

让我们先看一段示例代码:

public Drawable loadImageFromUrl(int id) {
        if(id<0 || id==0) {
            return null;
        }
        int targetdensity = mContext.getResources().getDisplayMetrics().densityDpi;
        BitmapFactory.Options opt = new Options();
        opt.inPreferredConfig = Bitmap.Config.RGB_565;
        opt.inScaled=true;
        opt.inTargetDensity=targetdensity;
        //inDensity bigger,image memory size smaller.now set to density=screendensityDpi*density
        //eg:density = (sw)320*(dpi)2
        opt.inDensity = (int)(targetdensity*mContext.getResources().getDisplayMetrics().density);
        opt.inJustDecodeBounds = false;
        InputStream is = null;
        Drawable drawable = null;
        try {
            is = mContext.getResources().openRawResource(id);
            /*Bitmap bitmap = BitmapFactory.decodeStream(is, null, opt);
            drawable = new BitmapDrawable(mContext.getResources(), bitmap);*/
            drawable = Drawable.createFromResourceStream(mContext.getResources(),null,is,null,opt);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try{
                    is.close();
                } catch (Exception e) {

                }
            }
        }
        return drawable;
    }
这段代码可以有效的降低图片资源的内存占用量,关键原因就是inDensity的设置。这个选项我还没有摸透他具体的意义。但是就查找到的资料来看,他是定义你要现实的图片的密度的。然而与我想象中完全相反的是,这个数值设置的越大,图片的压缩了就越高。一般我喜欢设置成手机屏幕的density乘以手机屏幕密度。如获取到手机的density是320,手机的像素密度是2,那么inDensity就设置为640。

因此,综上所述:

节省内存的加载图片方式为:

Drawable+Stream方式加载+压缩,如上面代码所示。

后期我如果找到了原理,再更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: