I have an Activity
in a TabHost
with 3 other activities. Hence, these are always alive (or in "on pause" state).
The first activity has four different images (~250kb each) and they are retrieving a lot of memory (around 80MB. Just to point out, I load the minimum size needed for the screen and I'm using layout_weight
if that helps), so I want to minimize the amount of memory which is needed.
I already tried to delete the images on the OnPause
state and set them again on OnResume
, but I didn't have luck, this is one example of what I was trying to do:
imageView.Drawable.Callback = null;
((BitmapDrawable)imageView.Drawable).Bitmap.Recycle();
imageView.Drawable.Dispose();
imageView.SetImageDrawable(null);
imageView.SetImageBitmap(null);
GC.Collect();
I don't know if deleting the Bitmap
on OnPause
is the best strategy, but it should work. I don't understand why the ImageView
isn't collected by the GC (since there are not external references)
EDIT This is how I'm loading the images. It doesn't work even if I put the images on the xml file. Besides, I don't care this code, I just want to dispose the bitmaps.
void SetBackgroundImages(int imageId, int resId, float width, float height) {
var imageView = FindViewById<ImageView>(imageId);
using (var bitmap = DecodeSampledBitmapFromResource(Resources, resId, width, height))
imageView.SetImageBitmap(bitmap);
}
public static Bitmap DecodeSampledBitmapFromResource(Resources res, int resId, float reqWidth, float reqHeight) {
var options = new BitmapFactory.Options {InJustDecodeBounds = true};
using (var b = BitmapFactory.DecodeResource(res,resId,options)){}
options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight);
options.InJustDecodeBounds = false;
return BitmapFactory.DecodeResource(res, resId, options);
}
At the end calling to
java.lang.System.gc()
after deleting the images did the trick.i saw this approach in several places, another one is the use of WeakReference to ImageView. These approaches can help GC to collect reference to ImageView properly