Android将drawable加载到ImageView中占用了大量内存

时间:2015-04-19 10:25:47

标签: android performance memory drawable

我遇到了问题。

我动态地将9 drawables加载到9 imageViews。 (drawables每次都不同)drawable id存储在对象类中,因此当我加载此drawable时,我使用ImageRessourceimageView设置为imageView.setImageRessource(myObject.getRessourceId()); 一切都运行正常但是当加载了9个drawable时,我在Android内存监视器上看到分配内存达到80MB并且我认为这不正常...(是吗?)

我尝试了不同的东西来解决它:

  • 使用Picasso库加载drawable。
  • 使用BitmapFactory.decodeResssource创建位图然后 imageView上的setImageBitmap。

使用我尝试过的所有技术,需要80MB的内存。

我尝试使用不同的图像分辨率,因此在ldpi(~30Ko /图像)和xhdpi(~87Ko /图像)中,但它并没有为每个加载的图像改变任何内容,它需要大约5MB的分配内存...

所以我的问题是:如何减少为图像分配的内存?

提前感谢您,如果有必要,我可以提供部分代码。

此致

PS:ImageViewsonCreate()方法动态创建的。{/ p>

3 个答案:

答案 0 :(得分:7)

感谢Bojan Kseneman的链接,我将分配的内存减少到30Mb。我正在使用这个:

imageView.setImageBitmap(Util.decodeSampledBitmapFromResource(getResources(), id, 150, 150));
  

Util是我项目的Utility类

使用这些方法:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

并且

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

答案 1 :(得分:1)

这是正常的,你记忆中最大的敌人是图像。另请注意,图像在内存中占用的空间比在磁盘上占用的空间大。加载需要很长时间也是正常的。解决方案是仅加载看到的大图像,并使用缓存下次更快地加载它们(您不需要再次下采样)。这是一篇文章,其中包含一个示例项目:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

答案 2 :(得分:0)

实际上,根据图像的性质,这可能没问题。由于使用了压缩算法,具有现代图像的文件大小不一定与其在内存中具有的大小有关。在内存中,所谓的小文件被扩展为实际的位图数据,这意味着RAM中将占用的数据多于SD卡/磁盘上的数据。

然而,来源(以及图像)将有助于进一步分析。

您还可以查看某些查看器中的图像,并尝试确定在该查看器中加载时占用的RAM量。您可能会对尺寸感到惊讶,这些图像占据了。这就是为什么具有严重依赖图像的主题的UI非常容易记忆。