Ori*_*man 12 java android caching bitmap
我是所有内存管理主题的新手,所以有很多我不理解的东西.
我正在尝试在我的应用程序中缓存图像,但我的内存消耗有问题:
所有的Bitmap Chaching代码都是从这里复制粘贴的:http://developer.android.com/training/displaying-bitmaps/index.html
我调试了代码并在eclipse的DDMS视图中检查了堆大小,在这些代码行之后大约有15mb的跳转:
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
在"decodeSampledBitmapFromResource"方法中.
图像是1024x800,75kb jpg文件.根据我在互联网上已经看到的内容,这个图像应该占用的内存量大约是1024*800*4(每像素字节数)= 3.125mb
关于这个主题的所有线程都没有说明为什么它会占用更多的内存.有没有办法用合理数量的内存缓存一个图像?
编辑
我尝试使用@ ArshadParwez下面的答案中建议的decodeFile方法.使用此方法,在BitmapFactory.decodeStream方法之后,内存仅增加了3.5mb - 问题解决了,但是我想直接从资源缓存位图.
我注意到在decodeResource方法中有2个内存"跳转" - 一个大约3.5mb - 这是合理的,另一个奇怪的是14mb.那些14mb用于什么,为什么会发生这种情况?
图像也根据密度进行缩放,因此可以使用大量内存.
例如,如果图像文件位于drawable文件夹(mdpi密度)中并且您在xhdpi设备上运行它,则宽度和高度都会加倍.也许这个链接可以帮助你,或者这个.
所以在你的例子中,图像文件将采用的字节是:
(1024*2)*(800*2)*4 = 13,107,200字节.
如果你在一台xxhdpi设备(如HTC和Galaxy S4)上运行它会更糟.
你能做什么?将图像文件放在正确的密度文件夹(drawable-xhdpi或drawable-xxhdpi)中,或将其放入drawable-nodpi(或在资源文件夹中),并根据需要缩小图像.
顺便说一下,你不必设置,options.inJustDecodeBounds = false  因为它是默认行为.实际上,您可以为位图选项设置null.
关于缩小比例,您可以使用谷歌的方式或我的方式每个都有自己的优点和缺点.
关于缓存有很多方法可以做到.最常见的是LRU缓存.我最近创建了一个替代方案(链接在这里或这里),它允许您缓存更多图像并避免使用OOM,但它会给您很多责任.
您可以使用此方法传递图像并从中获取位图:
public Bitmap decodeFile(File f) {
    Bitmap b = null;
    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        FileInputStream fis = new FileInputStream(f);
        BitmapFactory.decodeStream(fis, null, o);
        fis.close();
        int IMAGE_MAX_SIZE = 1000;
        int scale = 1;
        if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
            scale = (int) Math.pow(
                    2,
                    (int) Math.round(Math.log(IMAGE_MAX_SIZE
                            / (double) Math.max(o.outHeight, o.outWidth))
                            / Math.log(0.5)));
        }
        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        fis = new FileInputStream(f);
        b = BitmapFactory.decodeStream(fis, null, o2);
        fis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return b;
}
| 归档时间: | 
 | 
| 查看次数: | 9065 次 | 
| 最近记录: |