The task is to create a custom layout from the images. Created such a class that will resize images for a specific screen, without losing their quality. But now specific memory leaks. Who will tell?

public class ResizebleImageView extends ImageView { private Activity mActivity; private float mCoeficient; public ResizebleImageView(Context context, AttributeSet attrs) { super(context, attrs); mActivity = (Activity) context; mCoeficient = getCoeficient(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { System.out.println("Bytes per drawable " + ((BitmapDrawable)getDrawable()).getBitmap().getByteCount()); Drawable drawable = getDrawable(); if (drawable != null) { int width = MeasureSpec.getSize(widthMeasureSpec); int height; if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { height = MeasureSpec.getSize(heightMeasureSpec); } else { height = (int) Math.ceil((float) width * (float) drawable.getIntrinsicHeight() / (float) drawable.getIntrinsicWidth()); } setMeasuredDimension(width, height); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } private float getCoeficient() { DisplayMetrics ds = new DisplayMetrics(); mActivity.getWindowManager().getDefaultDisplay().getMetrics(ds); int screenWidth = ds.widthPixels; return screenWidth / 750f; } public void configureView(int width, int height, int leftMargin, int topMargin) { RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) (width * mCoeficient), (int) (height * mCoeficient)); params.leftMargin = (int)(leftMargin * mCoeficient); params.topMargin = (int)(topMargin * mCoeficient); this.setLayoutParams(params); } 

}

Here is the method call from the activation of this class from the activation. images as you can see not so much, and their size becomes colossal.

  sticks.configureView(459, 410, 106, 1610);/.ну и таких вызовов 7 штук для разных вьюх с разными размерами. 

    1 answer 1

    This is not a memory leak (you do not lose references to objects), but memory exhaustion - OutOfMemory (OOM).

    Occurs when trying to load inside ImageView content from which a component can choke.

    Your implementation, in fact, does not require any special additional memory allocations at all. So, this line, for example, simply copies the link to an object already in memory:

     Drawable drawable = getDrawable(); // OOM 

    The problem is that the size of resources (images) in bytes can be significantly larger than the application has: for example, if the size of the image placed in the ImageView is very large, then the amount of memory used for visual display will greatly increase. Observe the behavior of the GC in the application's memory monitoring debug panel.

    Here, for example, the use of memory when displaying 1 image size 480x360: enter image description here

    The same picture 1280x960: enter image description here

    The same image is 2048x1460: enter image description here

    Ie most likely, your problem is to use "uncombed" graphics resources - uncompressed and unmasked.

    • Yes, you are right about that. I understood that, but how would I process these images? let's say, those images that pull me a lot of memory are in my drawables. Get a bitmap and process it? - Bogdan Kolomiets
    • Bitmap with the wrong configuration of the pixel (and in general) "eat" even more memory. ImageView is configured by default for content scaling (as far as I remember, the scaleType property), so creating a custom class just for this purpose is not necessary. As a last resort, transfer responsibility for the scaling routine to the Picasso library, for example, and use it, but again, combing the sizes of the resources. Here it is worth understanding that image resizing is in any case a resource-intensive operation. - AseN
    • Well, the trick is that I have a layout of the images. Initially they occupy a little memory, and these images must be placed on the layout according to the given coordinates. I tried to manually calculate the dimensions in DP, but somehow I didn’t really work out. I took the size of these pictures for a specific screen and counted DP from here. In the end, everything was crooked. Perhaps tell me how to calculate these dimensions in DP that would be the same on all screens - Bogdan Kolomiets
    • Perhaps the absolute size in DP can be a good solution in dealing with OOM, but not a fact. It may also be that you should stop using ImageView to design your interface by going to WebView (which is also heavy, in general). It will not be possible to say something specific - it depends on your task. - AseN