On Nov 1, 2011, at 8:41 AM, Tomasz Cielecki wrote:
> By the way, is there a temporary solution in form of using JNI or
> something to implement the method?

See the attached patch.

Attachment: maps.patch
Description: Binary data


You're not expected to understand that. :-)

It's also a new area, that we really need to document, but there are three 
things of note in that patch:

 1. Android.Runtime.RegisterAttribute.DoNotGenerateAcw is a property 
(introduced in 1.9.x) which prevents generation of Android Callable Wrappers. 
This prevents the packaging process from trying to generate a 
"com.google.android.maps.ItemizedOverlay" type.

This allows us to create a new type which "mirrors" a Java type:

    [Register ("com/google/android/maps/ItemizedOverlay", 
DoNotGenerateAcw=true)]
    abstract class FixedItemizedOverlay : ItemizedOverlay {

Here, FixedItemizedOverlay has the same Java type as ItemizedOverlay -- 
com.google.android.maps.ItemizedOverlay.

 2. Every member that needs to be exposed to Java code needs to have a 
[Register] attribute. Note that the constructor and the CreateItem() members 
both have [Register] attributes.

The [Register] attribute has three parameters of note: The JNI name ("<init>" 
for constructors, "createItem" for the method), the JNI signature, and a 
"connector method."

 3. There's a lot of boilerplate for the connector method. :-)

The connector method is a static method which returns a System.Delegate and 
takes no parameters, and is called to get a delegate which is a JNI method 
suitable for use with JNIEnv::RegisterNatives:

        
http://download.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html#wp17734

If you look closely, every parameter of [Register] corresponds to a field of 
the JNINativeMethod JNI struct, and the delegate returned from the "connector 
method" needs to have the appropriate JNI method signature. Since in JNI, the 
first parameter is always a JNIEnv pointer, the second parameter is either the 
instance reference or a class reference, followed by any method parameters, the 
JNI signature we need is:

        static IntPtr _CreateItem(IntPtr /* JNIEnv* */ env, IntPtr /* jobject 
*/ __self, int index) {...}

The connector method thus returns a delegate which references the JNI method to 
register.

Which brings us to the JNI method itself, which needs to map JNI parameters 
into actual managed types, for which we use Java.Lang.Object.GetObject<T>():

        FixedItemizedOverlay self = 
Java.Lang.Object.GetObject<FixedItemizedOverlay>(__self, 
JniHandleOwnership.DoNotTransfer);

Finally, our JNI method needs to return a Java value. You could do:

        return value == null ? IntPtr.Zero : value.Handle;

though JNIEnv.ToJniHandle(value) is easier to do.

Hope this helps,
 - Jon

_______________________________________________
Monodroid mailing list
[email protected]

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to