Insaf Mirza
Insaf Mirza

Reputation: 69

OutOfMemory error on Continues swipe of Viewpager that has used Glide to load bitmaps into it

I am trying to develop an image gallery application. The Error occurs in the page mentioned. When my page loads I have an Image View within a ViewPager and a horizontal strip at the bottom where I have used recycler view.On load

The first image loads on the ViewPager's imageview and the corresponding images thumbnail gets highlighted on the horizontal strip. When clicking on a thumbnail at bottom horizontal strip, the corresponding image loads on the Viewpager's image view. All my functionalities are working as desired. But when I continuously swipe the viewpager even after giving large heap for my application the app becomes unresponsive/crashes. From the log and Android Monitors Memory graph I could clearly make out that its a OOM error. Now comes the key factor I have used Glide to load images into the image view of viewpager. To make sure Glide frees up the bitmap it uses I have used the following methods:

Glide
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)

I have also called,

  Glide.get(context).clearMemory();
        AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            //TODO your background code
            Glide.get(context).clearDiskCache();
        }
    });

within destroyItem method of View pager.

Also, I have used the following glide code to load bitmap image into image view:

Glide
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
     mediaDetails.get(curPos).getFullImageView().setImageBitmap(resource);
                         }
      }

I need a bitmap resource since I have implemented Zoom and Pan functionalities on the image view. What will be the most effective way to free up the bitmap created when the view pagers view get destroyed. Or is there any other way to handle this issue? Your help would be most valuable.

Upvotes: 2

Views: 466

Answers (3)

Wilder Pereira
Wilder Pereira

Reputation: 2267

If moving to another library is not a problem, I recomment you to use Fresco.

According to a one of the engineers on the Fresco project:

Images aren't stored in the Java heap, but in the ashmem heap. Intermediate byte buffers are also stored in the native heap. This leaves a lot more memory available for applications to use. It reduces the risk of OutOfMemoryErrors. It also reduces the amount of garbage collection apps have to do, leading to better performance.

Upvotes: 0

Ramz
Ramz

Reputation: 935

Try the below code, This will help you to resize the bitmap and stop OutOfMemory exception.

Initialize the variables,

private static final int MAX_WIDTH = 370;
private static final int MAX_HEIGHT = 370;

Set image in imageview using glide,

Glide.with(context_tab1).load(url).error(R.drawable.loader_bg).placeholder(R.drawable.loader_bg).transform(new BitmapTransform(MAX_WIDTH, MAX_HEIGHT)).into(holder.image);

Add the below code for bitmap transform,

public class BitmapTransform implements Transformation {

    int maxWidth;
    int maxHeight;

    public BitmapTransform(int maxWidth, int maxHeight) {
        this.maxWidth = maxWidth;
        this.maxHeight = maxHeight;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        int targetWidth, targetHeight;
        double aspectRatio;

        if (source.getWidth() > source.getHeight()) {
            targetWidth = maxWidth;
            aspectRatio = (double) source.getHeight() / (double) source.getWidth();
            targetHeight = (int) (targetWidth * aspectRatio);
        } else {
            targetHeight = maxHeight;
            aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            targetWidth = (int) (targetHeight * aspectRatio);
        }

        Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
        if (result != source) {
            source.recycle();
        }
        return result;
    }

    @Override
    public String key() {
        return maxWidth + "x" + maxHeight;
    }

}

Upvotes: 1

masoud vali
masoud vali

Reputation: 1536

when you are loading use override to resize the bitmap:

Glide  
.with(context)
.load(url)
.override(200, 200)
.into(imageView);

Upvotes: 1

Related Questions