On Jan 4, 2012, at 9:06 PM, Wally McClure wrote:
> Thanks.  Christntr got me set on this.

For the benefit of everyone else... ;-)

> The problem is that nothing in myDragListener seems to fire.  I think the 
> problem is when I instantiate the class, I am handing in the incorrect handle.

>         protected class myDragEventListener : View.IOnDragListener

Unless you're me [0], always, _always_, ALWAYS inherit from Java.Lang.Object 
when implementing an Android interface.

Here's why: the IJavaObject.Handle property is the JNI handle of the Java-side 
object to pass as a parameter. This thus requires that you have a Java-side 
object to provide (and is why any IJavaObject.Handle implementation which 
throws an exception or returns IntPtr.Zero is broken). Subclassing 
Java.Lang.Object handles creating the Java-side instance automatically.

Furthermore, the associated Java object needs to be "correct." If you're 
implementing an interface (as `myDragEventListener` does), and passing an 
instance of that type to a Java method (your previous `iv.SetOnDragListener()` 
call), then IJavaObject.Handle will be used to obtain the Java instance to use, 
and _that_ instance will be passed to the Java-side setOnDragListener() method.

That Java-side instance had better implement the Java View.OnDragListener 
interface. If it doesn't...anything could happen. (ClassCastExceptions, aborts, 
corruption...)

In your case, you're doing:

        IntPtr IJavaObject.Handle {
                get {return _c.Handle;}
        }

where `_c` is a Context instance. Unless `_c` is your Activity _and_ your 
Activity is also implementing View.IOnDragListener, you'll be providing a Java 
object which does _not_ implement the Java VIew.OnDragListener interface.

This is, suffice it to say, Badâ„¢.

If you instead subclass Java.Lang.Object (as you should!), an Android Callable 
Wrapper (ACW) will be generated, which will implement the Java-side interfaces 
which are present in your subclass. The ACW will be created in the 
Java.Lang.Object constructor, thus ensuring that the Handle property is mapped 
to an appropriately typed Java instance.

Finally, there's the GC problem. Java.Lang.Object has support for cross-VM 
object references. If you implement IJavaObject yourself, your class won't, and 
you'll need to (somehow) ensure that your Java object is eventually freed. 
Worse, you'll need to figure out some way to keep the managed instance from 
being GC'd as long as the Java object is alive. Don't go there, just subclass 
Java.Lang.Object.

 - Jon

[0] ...and I would avoid implementing IJavaObject manually unless there was 
absolutely no other alternative. Please, just don't.

_______________________________________________
Monodroid mailing list
[email protected]

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

Reply via email to