The NullPointerException is thrown from Java code:
in android.graphics.Bitmap.createBitmap (Bitmap.java:687) at android.graphics.Bitmap.createBitmap (Bitmap.java:707) in dalvik.system.NativeStart.run (native method)
Looking at the many releases, Jelly Bean can fit:
https://github.com/android/platform_frameworks_base/blob/jb-release/graphics/java/android/graphics/Bitmap.java#L687
return nativeCreate(colors, offset, stride, width, height, config.nativeInt, false);
A quick look at the surrounding method body indicates that config not checked for absence, so if null passed, this will throw a NullPointerException.
The problem is that you are not passing null:
using (Bitmap.Config config = Bitmap.Config.Rgb565) { return Bitmap.CreateBitmap (blurredBitmap, width, height, config); }
... or you?
I would suggest that you remove the using block:
return Bitmap.CreateBitmap (blurredBitmap, width, height, Bitmap.Config.Rgb565);
Here I think what might happen, but first, a digression:
The core of Xamarin.Android is the mapping between Java objects and their corresponding C # shell objects. Constructor call, Java.Lang.Object.GetObject (), etc. create mappings; Java.lang.Object.Dispose () removes the mappings.
The main part of this is Object Identity: when a Java instance is exposed to C # code and a C # wrapper is created, the same C # wrapper instance should still be reused for that Java instance.
An implicit consequence of this is that any instance is effectively global, because if there are several code paths / flows, etc. get the JNI handle for the same java instance, it will get the same c # shell.
Which brings us back to my hypothesis, and your code block: Bitmap.Config is a Java enumeration meaning that every element is a Java object. In addition, they are global values, so each thread has access to these members, that is, the C # Bitmap.Config.Rgb565 instance is effectively a global variable.
The global variable that you use Dispose ().
What is “excellent”, since next time a new shell will be created by Bitmap.Config.Rgb565.
The problem, however, is that if you have multiple Bitmap.Config.Rgb565 threads at the same time, each of which tries to Dispose () the instance. At this point, it is plausible that these two threads can reference the same wrapper instance, and Dispose () from one thread will thus be an INVALIDATE instance used by the other thread.
Which will cause null be passed to the Bitmap.createBitmap () call that you are observing.
Try removing the using block and see if that helps.
What a gc for!
(insert cough and laugh here.)
We can pet a little. I will argue that this is NOT a memory leak, because memory is well rooted and well known; permanent access Bitmap.Config.Rgb565 will return the previously created instance, do not constantly create new instances. There is no "leak" in this.
Instead, I will argue that the instance and underlying GREF are “Tax”; it is “burnt,” part of the cost of doing business. Although it would be "nice" to minimize these costs, it is impractical to remove all of them (for example, we "lose" GREF per class through .class_ref, which is used to search for method labels ...), at least not with current architecture.
(I also cannot imagine an alternative architecture that would lead to different costs / “taxes.” Although I have some thoughts on resolving things that need to be improved for some areas, they are not huge.)
I would advise you not to worry about Bitmap.Config.Rgb565 and the like too many members unless / until the profiler or GREF shows otherwise.