Looks like Thread.Sleep()
is called to give the garbage collector enough time to do its job bebore trying to recreate the Bitmap
should an OutOfMemoryError
have occurred at first attempt. At second attempt, lower standards are used to consume less memory: RGB_565
instead of ARGB_8888
.
It would be better (more efficient / easier to read / stronger / less dangerous for concurrent applications) to test the amount of available memory before trying to create the Bitmap
the first time, rather than catching OutOfMemoryError
.
Thread.sleep(100)
, on its side, assumes that the garbage collection will be initiated and will complete within 100ms, which is absolutely arbitrary. It may have not started yet, it may be still running...
And anyway, calling System.gc()
is not helpful here as the garbage will be collected anyway. The VM detects that and won't wait should there be a lot of garbage to collect.
So my suggestion is:
- Forget about these
System.gc()
andThread.Sleep()
calls. They are not efficient/helpful. - Test the amount of available memory before trying to create the
Bitmap
the first time. You can determine the size of the future resultingBitmap
as you know its size and encoding. (Refs: Runtime and ActivityManager) - Should the amount of memory left be low, why not reducing the standards if the resulting
Bitmap
fits (16 bits RGB instead of 32 bits ARGB). - Should this be unsufficient, logging an error and/or displaying an alert (depending on your app, I don't know the context) is fine.
Two interesting related articles from the Android team: