In my main activity (with launchmode set as singleTask), I have a TabHost with three tabs, which all contain a custom Gallery that displays Views containing a bitmap image which is stored locally (once we have server support, these will be downloaded instead).
The problem I am running into is the java.lang.OutOfMemoryError: bitmap size exceeds VM budget error (on my emulator. It works terrific on my Galaxy Tab). I understand that this means I am using too many bitmaps of large sizes without recycling them, however I am having difficulty figuring out the best place to recycle them, since each tab remains running in the background when another tab is selected.
Do I need to change my Gallery adapter to only have a few bitmaps loaded at once (such as the selected, left, and right views), or is there a simpler solution (for example, a good place to call recycle())?
Edit:
I tried using this code, and called it when a new gallery item is selected. It worked at first, but then the app still crashed. Am I not calling recycle() correctly?
/* *
* Set the current, left, and right view's images. Set all others to NULL and recycle them.
*/
public void refreshImages() {
for (int i = 0; i < adapter.getCount(); i++) {
View v = adapter.getView(i, null, null);
ImageView img = (ImageView) v.findViewById(R.id.add_image);
Thing mything = adapter.getThing(i);//returns a Thing object at this position in the gallery.
if (i == currentGalleryPosition //This is set when the gallery item is selected.
|| i == (currentGalleryPosition - 1)
|| i == (currentGalleryPosition + 1)) {
img.setImageBitmap(thing.getImage(this)); //This retrieves the bitmap from my drawable resources.
img.setScaleType(ImageView.ScaleType.FIT_XY);
}
else {
Bitmap bmp = thing.getImage();
img.setImageBitmap(null);
bmp.recycle();
}
}
}
This is not the best solution, but it does what I need it to do:
When decoding a bitmap, set the inPurgeable and inInputShareable options to true. This makes it so that if the VM needs more space, it can simply remove images (purge), but if you are sharing multiple images amongst multiple tabs, the inInputShareable option allows the decoder to simply share the same location in memory, without creating a new instance of the same bitmap.