Android loading drawable into ImageView taking a lot of memory

放肆的年华 提交于 2019-12-04 19:26:24

This is normal, the biggest enemy of your memory are images. Also note that images take more space in memory than on the disk. It is also normal that it takes long time to load. The solution is to only load as big image as it is seen and using caches to load them faster next time (you don't need to downsample again). Here is an article with a sample project with just that: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Thanks to the link of Bojan Kseneman, I reduces the allocated memory to 30Mb. I'm using this:

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

Util is a Utility class of my project

with those methods :

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

And

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

Depending on the nature of the image, this can be ok, actually. The filesize with modern images does not necessarily relate to the size it will have in memory, due to the compression algorithms used. In memory, the supposedly small file is expanded into the actual bitmap data, which means more data will be occupied in RAM than on sd-card/disk.

However, the sources (as well as the images) would be helpful for further analysis.

You could also take a look at the images in some viewer, and try to identify how much RAM it occupies when being loaded in that viewer. You might be surprised about the size, such images occupy. That's why UIs with themes that rely heavily on images are so memory-eating.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!