Android - Bitmap.CreateBitmap - null pointer exception

Sometimes, when I try to create a blurry bitmap, I get a "Null Pointer Exception".

Happens in this block of code (I recently started catching an exception, so at least it doesn't crash the application):

try { using (Bitmap.Config config = Bitmap.Config.Rgb565) { return Bitmap.CreateBitmap (blurredBitmap, width, height, config); } } catch (Java.Lang.Exception exception) { Util.Log(exception.ToString()); } 

For more information about the parameters that I pass to the CreateBitmap method, see these figures:

enter image description here

Here are the advanced options:

enter image description here

Full exception:

exception {Java.Lang.NullPointerException: type exception Thrown "Java.Lang.NullPointerException". in System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in / Users / builder / data / lanes / 2058 / 58099c53 / source / mono / mcs / class / corlib / System.Runtime.ExceptionServices / ExceptionDispatchInfo.cs: 61 on Android.Runtime.JNIEnv.CallStaticObjectMethod (IntPtr jclass, IntPtr jmethod, Android.Runtime.JValue * parms) [0x00064] in / Users / builder / data / lanes / 2058 / 58099c53 / source / monodroid / src / Mono.Android src / Runtime / JNIEnv.g.cs: 1301 on Android.Graphics.Bitmap.CreateBitmap (colors System.Int32 [], Int32 width, height Int32, configuration Android.Graphics.Config) [0x00088] in / Users / builder / data / lanes / 2058 / 58099c53 / source / monodroid / src / Mono.Android / platforms / android-22 / src / generated / Android.Graphics.Bitmap.cs: 735 on Psonar.Apps.Droid.PayPerPlay.StackBlur.GetBlurredBitmap (Android .Graphics.Bitmap original, radius Int32) [0x00375] in d: \ Dev \ psonar \ Source \ Psonar.Apps \ Psonar.Apps.Droid \ Psonar.Apps.Droid.PayPerPlay \ Utilities \ StackBlur.cs: 123 - - End of managed exception stack trace --- java.lang.NullPointerException at android.graphics.Bitmap.createBitmap (Bitmap.java:687) in android.graphics.Bitmap.createBitmap (Bitmap.java:707) in dalvik.system. NativeStart.run (native method)} Java.Lang.NullPointerException

Not sure if this could be an error in Xamarin or the parameters passed are incorrect.

+5
source share
1 answer

I received a response from one of the Xamarin team members: Jonathan Prior:

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.

The whole stream is available here.

Then I asked:

Jonathan Prior - Welcomes the offer. My question is, if I delete the using statement, will it lead to a memory leak? Bearing in mind if I stop deleting a new instance of the configuration?

He replied:

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.

+2
source

All Articles