2

In the documentation, titled "Managing Bitmap Memory" you can find the following statement:

Caution: You should use recycle() only when you are sure that the bitmap is no longer being used. If you call recycle() and later attempt to draw the bitmap, you will get the error: "Canvas: trying to use a recycled bitmap".

So, what exactly means "no longer"?

I call setImageDrawable(drawable) in my fragments onCreateView(...) method. And I call recycle() on the drawable's bitmap in the fragment's onStop(). When the user now leaves the fragment by launching another activity the bitmap is recycled. But when the user comes back to the previous fragment, its onCreateView() is called again, resulting in a new call to "setImageDrawable(drawable)". And this throws:

IllegalArgumentException: Cannot draw recycled bitmaps

So, I still seem to be in the "no longer" context. When do I get a new bitmap, which is not recycled? Only after the fragment and its activity have been completely destroyed?

Sebastian Engel
  • 3,500
  • 32
  • 30
  • Your bitmap will get GCed automatically when you leave the activity (so long as you don't have any long lived references to it). Unless you need to manage many bitmaps while the activity is alive (for memory management) there's no need to manually recycle them. – dymmeh Aug 28 '13 at 14:42
  • 1
    The problem is the following: The app has multiple sections. On a tablet, most of the sections have a background image, that fills the screen. So loading such an image takes a lot of memory. When the user switches to another section, the previous activity is only stopped, not destroyed immediately (image is not GCd). So coming to another section loads another image into the heap (which grows) and so on. I already sample the image down when loading it, but actually this only delays the OutOfMemory error. – Sebastian Engel Aug 28 '13 at 18:33
  • So therefore I call recycle() and Runtime.gc() in onStop(). But this results in "Cannot draw recycled bitmaps" when the user comes back to that section which wants to load the same (recycled) image as before. – Sebastian Engel Aug 28 '13 at 18:37

1 Answers1

2

So, what exactly means "no longer"?

No longer means you are not going to use the same reference of Bitmap.

As you told you are recycling bitmaps on onstop(), try with this also inside your onStop()

   if(bitmap!=null)
   {
      bitmap.recycle();
      bitmap=null;
   }

Bitmap and outOfMemory in android

Watch first 20 minuts of this official video if you want to make your day good - http://www.youtube.com/watch?v=_CruQY55HOk

Community
  • 1
  • 1
T_V
  • 17,440
  • 6
  • 36
  • 48
  • Hi Tarun, I've seen this video. And i got everything. I solved my problem now by implementing a caching mechanism as documented at [Displaying Bitmaps Efficiently](http://developer.android.com/training/displaying-bitmaps/index.html). So when initially loading the image, I put it into the cache. Then in onStop() I recycle it, run the GC (-> frees memory) and later when the same fragment is shown again, I load the image from the cache. As the images are really large, I still sample them down. As this takes time it makes sense to store them in a disk cache additionally. – Sebastian Engel Aug 30 '13 at 10:35
  • Then what is you prob now? – T_V Aug 30 '13 at 11:24