Android loading drawable into ImageView taking a lot of memory

試著忘記壹切 提交于 2019-12-06 09:55:04

问题


I'm having a problem.

I'm loading 9 drawables into 9 imageViews dynamically. (drawables are different each time) The drawable id is stored in the object class so when I load this drawable I set the ImageRessource to the imageView by using imageView.setImageRessource(myObject.getRessourceId()); Everything is working fine but when the 9 drawables are loaded, I see on the Android Memory Monitor that the allocate memory reaches 80MB and I think this isn't normal... (Is it?)

I tried different things to solve it:

  • Load the drawable with the library Picasso.
  • Use BitmapFactory.decodeResssource to create a Bitmap and then setImageBitmap on the imageView.

With all the techniques I tried, it takes 80MB of allocated memory.

I tried using different image resolution so in ldpi (~30Ko/image) and in xhdpi (~87Ko/image) but it doesn't change anything for each image loaded it takes about 5MB of allocated memory...

So my question is : How can I reduce the allocated memory for thoses images?

Thank you in advance, I can give parts of code if it's necessary.

Regards

PS: The ImageViews are created dynamically in the onCreate() method.


回答1:


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




回答2:


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



回答3:


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.



来源:https://stackoverflow.com/questions/29728573/android-loading-drawable-into-imageview-taking-a-lot-of-memory

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