0

I have an application with a lot of pages and each of them have their own image which is loaded from web with an asynctask. The problem is when you open and close a lot of pages, after some time it gives the outofmemory error. How to clear the image from memory when leaving the activity to prevent this?

The images are loaded by this Asynctask:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap mIcon11 = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon11 = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return mIcon11;
        }

        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }

by calling:

new DownloadImageTask((ImageView) findViewById(R.id.ivCard)).execute("http://myurl.com/example.png");

This activity is opened and closed with different values and different images. After opening some instances of this activity, it gives the following outofmemory error:

07-24 16:37:57.870  27717-28014/com.yigitserin.hsboard E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.OutOfMemoryError
            at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
            at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:650)
            at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:722)
            at com.yigitserin.hsboard.HeroActivity$DownloadImageTask.doInBackground(HeroActivity.java:137)
            at com.yigitserin.hsboard.HeroActivity$DownloadImageTask.doInBackground(HeroActivity.java:125)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)

How to remove the image from memory after the user quits one instance of this activity?

user3686811
  • 137
  • 1
  • 2
  • 9

4 Answers4

2

You need to call the recycle method for the bitmaps, eg. in your activies onDestroy/onStop methods.

See Recycle ImageView's Bitmap

Community
  • 1
  • 1
dthomasen
  • 826
  • 15
  • 32
1

In my opinion you have to use third party lib like :-

Universal Loader

Picasso

URL helper

Above lib maintain bitmap memory automatically.

duggu
  • 37,851
  • 12
  • 116
  • 113
0

I think You should close the stream in finally block and then give a try.i hope this can rule out one possibility then we can think of other optimization techniques.

Amit Jain
  • 143
  • 8
0

You likely don't need to "clear" the memory but rather downsample the Bitmap you are loading to avoid the out of memory exception. There are some good tutorials on how to process and load large bitmap files. For example:

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

Here rather than loading the entire bitmap you can scale down the image prior to loading into memory and avoid this issue entirely.

If you're still running into the problem, I would sooner be concerned with why you have an application that is keeping references to a lot of images it is no longer using. When pages are destroyed the bitmaps should be garbage collected like anything else if your app is set up correctly.

Rarw
  • 7,645
  • 3
  • 28
  • 46