Hanzo
Hanzo

Reputation: 1899

Throwing OutOfMemoryError with large images

I'm working on a way to hold the same aspect of my images (icons and images) in my "universal" app.

The problem with the resolutions/screens densities is causing me a lot of headaches.

Is there any way to work with this problem:?

Device: Tablet 10" / 1280x752 / Screen density MDPI

If I create one image for each density, in devices with large resolution and low screen density the images show small.

My solution is working with large images and scale down it to the images not show pixelized.

I'm working with official solution Android

This is a part of my activity

    @Override   
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_test);
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        widthScreen = size.x;
        heightScreen = size.y;      
        imgTest = (ImageView)findViewById(R.id.image);

        imgTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

           final Bitmap img = decodeSampledBitmapFromDrawable(Test.this,tipoprueba, widthScreen, heightScreen);
        imgTest.setImageBitmap(img);

                    }

        });

    }


public static Bitmap decodeSampledBitmapFromDrawable(Context activity,String res, int reqWidth, int reqHeight) {

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(activity.getResources(), activity.getResources().getIdentifier(res, "drawable", "com.example.docaper"), options);
        options.inSampleSize = Utils.calculateInSampleSizeInside(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        options.inScaled = false;
        return BitmapFactory.decodeResource(activity.getResources(), activity.getResources().getIdentifier(res, "drawable", "com.example.docaper"), options);
    }



    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

        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;

            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
        }

When click in the image, I change the image.When I change several images a OutOfMemory can't allocate ... exception is showed and closes the app.

Any ideas?

Thanks a lot

Upvotes: 2

Views: 4244

Answers (1)

Chris Handy
Chris Handy

Reputation: 366

The following has worked for me in similar situations: Android doesn't really free a bitmap after it drops out of scope. Leaving a high memory usage that quite often does not get cleaned.

Keep a handle to the bitmap you are setting

private Bitmap storedBitmap = null;

Change the OnClickListener() to:

imgTest.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

       final Bitmap img = decodeSampledBitmapFromDrawable(Test.this,tipoprueba, widthScreen, heightScreen);
       imgTest.setImageBitmap(img);

       if(storedBitmap != null){
           storedBitmap.recycle();
           storedBitmap = null;
       }
       storedBitmap = img;

    }

});

Upvotes: 1

Related Questions