Xamarin Android Bitmaps Part 3 – Bitmap Cleanup Methods

In this post I’ll be sharing some code I use across my Xamarin Android apps for managing bitmap memory cleanup.

Advertisements

This is part three of the bitmaps mini-series of posts. 

If you skipped part 1 and 2, that’s okay for this post, but it will help you have a much stronger understanding of why the code works how it works if you do read parts 1 and 2. For this post, I’ll be sharing some code I’ve used across Xamarin Android projects that helps with cleaning up android bitmaps.

Shared

For methods I’ll be using across entire apps, I like to put them in a static class called Shared, where all methods and members are static. This enables easy use of general purpose methods across all activities, classes, etc. Just for anyone who doesn’t know, static classes in C# only have one instance, and they cannot be instantiated, members and methods are invoked by simply using the class name. This also means that static classes are garbage collector roots that never get cleaned up, meaning however big that class is on the heap, that class occupies that much memory for the entirety of the lifecycle of the app. Anyways, let’s move on.

 Generic sweeping across runtimes

First and foremost, you’re going to need a method to do major collections across both runtimes, you don’t technically have to do this, but if you need memory freed right then and there, you do. For this, I create a generic method called Sweep (sorry about the dots, wordpress sucks at formatting code):

....public static void Sweep()
....{
........GC.Collect();
........Java.Lang.JavaSystem.Gc();
....}

So as you can see, this is pretty simple, calling Sweep simply invokes both runtimes garbage collectors.

Cleaning bitmaps

Cleaning bitmaps takes a little bit more code, but not too much, to clean a bitmap I use the following code:

....public static void CleanBitmap(Bitmap bitmap, bool sweep = true)
....{
........if (!bitmap.IsRecycled)
........{
............bitmap.Recycle();
............bitmap.Dispose();
............bitmap = null;
........}
........if (sweep)
........{
............Sweep();
........}
....}

This method takes a bitmap to be cleaned, and a boolean sweep. Since major collections are expensive and take a long time to do, I like to be able to specify when I’d like a sweep to occur, so if I have say 10 bitmaps that need cleaned, I can pass false and manually call sweep, or I can pass true and the sweep will occur as a part of the bitmap cleanup. Besides that, this method checks if the bitmap has been recycled to avoid accidentally trying to recycle a recycled bitmap which would case a crash, and if it hasn’t been recycled, it recycles, disposes, and nulls out the bitmap, which frees the bitmap memory, disposes the mono handle, and nulls out the bitmap to break the cyclic reference between the two runtimes.

Cleaning image view bitmaps

The final method I use for cleaning bitmaps allows me to easily clean up bitmaps that are tied to an image view, the code is as follows:

....public static void CleanImageViewBitmap(ImageView imageView, bool sweep = true)
....{
........Drawable drawable = imageView.Drawable;
........if (drawable is BitmapDrawable)
........{
............BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable;
............if (bitmapDrawable.Bitmap != null)
............{
................Bitmap bitmap = bitmapDrawable.Bitmap;
................if (!bitmap.IsRecycled)
................{
....................imageView.SetImageBitmap(null);
....................imageView.Dispose();
....................bitmap.Recycle();
....................bitmap.Dispose();
....................bitmap = null;
................}
............}
........}
........if (sweep)
........{
............Sweep();
........}
....}

 

Pretty similar to the CleanBitmap method from before, except in this case we pass an image view, get it’s bitmap drawable, make sure it’s not null and hasn’t been recycled, and we set the image view bitmap to null, dispose the image view, and repeat for the bitmap itself. This will ensure that the entirety of the image view gets cleaned up. Just like before, we can optionally decide if we want a sweep to occur or not.

In terms of bitmap cleanup, that’s all there really is to it, everything else you may need to do should just be variations of this code. In the next post, we’ll look at optimizing loading bitmaps to reduce memory overhead, which is the other big part of the equation. Thanks for reading, and if you have any question, comments, or concerns with anything I said, feel free to leave a comment or email me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

Advertisements
Advertisements
%d bloggers like this: