4

Possible Duplicate:
OutOfMemory Exception when handling images

I have a Bitmap creation within a AsyncTask, which goes like this:

private WeakReference<Bitmap> myBitmap;
private WeakReference<Bitmap> endResultBitmap;
private ImageView imv;

...

private class SendBitmap extends AsyncTask<Integer, Void, Bitmap> {

public SendBitmap(Bitmap bitmap) {
    myBitmap = new WeakReference<Bitmap>(bitmap);
}

@Override
protected Bitmap doInBackground(Integer... params) {
  Bitmap bm = null;
  bm = getBitmapFromNet(params[0]);

  return bm;
}

And then I want to create Bitmap on which the received Bitmap would appear twice (one next to another)

protected void onPostExecute(Bitmap result) {
  endResultBitmap = new WeakReference<Bitmap>(Bitmap.createBitmap(result.getWidth() * 2, result.getHeight(), result.getConf()));

  Canvas canvas = new Canvas(endResultBitmap.get());
  canvas.drawBitmap(result, 0, 0, null);
  canvas.drawBitmap(result, result.getWidth(), 0, null);

  imv.setImageBitmap(endResultBitmap);
}

then I have my onCancelled() method:

@Override
protected void onCancelled(Bitmap result) {
  if(endResultBitmap!=null) {
    endResultBitmap.recycle();
    endResultBitmap = null;
  }
}

The thing is that if I execute this AsyncTask couple of times, the heap grows as mad. I execute the AsyncTask when a button is pressed, but at first I do:

public void onClicked(View v) {

  if(asyncTaskInstance != null) 
    asyncTaskInstance.cancel();

  asynctaskInstance.execute(2);
}

But again, the Heap grows as mad and at some point it will crash with OutOfMemoryError.

Any idea? Do I have something wrong in my Design of the task?

Community
  • 1
  • 1
Peter Olsbourg
  • 487
  • 2
  • 7
  • 12

1 Answers1

1

Android has some memory limits for apps (16 MB if i remember correctly), and that image is too big in an uncompressed format. Theres some interesting discussion in this question.

To solve it, there are afaik only two ways:
1. Reduce the size of the image to consume less memory
2. Load the image in native code using the NDK.

To 1.: I don't know what exactly you are trying to do and can't tell if thats really a viable option. If it is, you may want download the image file from the net and open it with the BitmapFactory class. There are some static functions that take an BitmapFactory.Options object. Use inSampleSize from this Options object to reduce the image size by a certain factor at loading time (inSampleSize should be a power of two by the way).

To 2.: The memory limits that I mentioned above don't apply to native code. So you may be able to load the image and display in a native way. I don't have any experience with that, I just know that it's possible, but googling around should turn up a few results.

Community
  • 1
  • 1
  • I cannot resize since I need that quality I get from the web. – Peter Olsbourg Aug 08 '11 at 13:48
  • As said above, if you can only download one fixed quality from the web, download the whole image from the web and save it in a cache directory. From there, load it via the BitmapFactory with a reduced size into the memory to circumvent the restrictions. –  Aug 08 '11 at 13:52
  • I will try that. Just for info, now if I click the Button 10 times, it will start 10 different AsyncTasks and at some point will throw "Grow heap (frag case) to 221.454MB for 14313056-byte allocation" message and OutOfMemoryException after that. – Peter Olsbourg Aug 08 '11 at 13:56