On Dec 6, 2011, at 11:51 AM, klimaye wrote:
> I was using the constructor below to integrate with zxing bar code scanner.
>
> IntPtr rAlertDialog = JNIEnv.CallStaticObjectMethod(
> IntentResult, IntentResult_initiateScan, new
> JValue(activity));
> // ...and construct a nice managed wrapper over the Java
> instance.
> new AlertDialog(rAlertDialog, JniHandleOwnership.DoNotTransfer);
Given that JNIEnv.CallStaticObject() returns a local ref, unless you're calling
JNIEnv.DeleteLocalRef() later in the code, you really want
JniHandleOwnership.TransferLocalRef.
The new way is the same as the old abstract-class-or-interface way:
var dialog = new Java.Lang.Object (rAlertDialog,
JniHandleOwnership.TransferLocalRef)
.JavaCast<AlertDialog>();
> Why was this done? What is an alternate way of achieving above now in 4.0?
The primary reason is to reduce user error. "Back in the day," all non-abstract
types had a public IntPtr constructor, and often this was the _only_
constructor on the type. This resulted in numerous people doing the (very sane):
var value = new SomeType (IntPtr.Zero);
value.SomeMethod();
and wondering why `value.SomeMethod()` dies with a NullPointerException. In
short, while this worked, it was very brittle.
Later, we kept the constructors, but renamed the parameter to "doNotUse" so
people wouldn't use it. That wasn't really good either. :-)
Since we had to change all the constructors anyway (to add the
JniHandleOwnership parameter, which works around a JNI limitation), we figured
we'd make the constructors protected as well, thus removing the ability to
easily "misuse" the constructor. This also increases consistency with abstract
types and interfaces, neither of which could be instantiated via `new` anyway
and required the JavaCast extension method.
- Jon
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid