On Mar 30, 2012, at 11:18 AM, Chris Tacke wrote:
> I had come to the conclusion about inheriting from Java.Lang.Object as well, 
> and that got the service working.  I'm one of those "likes to understand the 
> internals" personalities, so I'm still interested in what the IJavaObject 
> interface requirements are - but only if you have the time and some pointers 
> on resources.

IJavaObject is a bridging interface; it demarcates "Peer objects" (objects 
which have both a managed side and a Java side). For every Android-callable 
type+instance (e.g. an Activity subclass, or an implementation of 
java.lang.Runnable), there needs to be a Java-side type+instance to invoke.

For example, consider android.app.Activity.runOnUiThread(), which takes a 
java.lang.Runnable parameter. android.app.Activity instances are Native peers.

Meanwhile, C# code has Android.App.Activity.RunOnUiThread(), which takes a 
Java.Lang.IRunnable parameter. (There's also an Action parameter, which 
delegates to the IRunnable overload.) Android.App.Activity instances are 
Managed peers to android.app.Activity Native peers.

Android knows nothing of C# code, so what happens when you call 
Activity.RunOnUiThread(IRunnable)? Mono for Android passes a Java instance to 
Activity.runOnUiThread(); this instance is called a Native Peer.

What Java instance? Whatever Java instance IJavaObject.Handle refers to.

The requirement, then, is that IJavaObject.Handle return a JNI handle (usually 
a global reference) to a Java-side Naive peer instance. Furthermore, the Native 
peer must implement whatever interfaces a required at the callsite; e.g. if you 
call Activity.runOnUiThread(), the returned instance needs to be of a type that 
implements Runnable. Failure to do so results in interesting runtime type 
coercion errors. :-)

Is it possible to do this manually? Yes. Would you want to? Probably not.

...then we get to the GC, in which you want (need) to have both GCs 
interoperate with each other. Java.Lang.Object has support for this. Whatever 
IJavaObject implementation you cook up will not, and unless your managed object 
is somehow rooted (static variable?), there's no way to keep Mono's GC from 
collecting your object when Java is still referring to the Native peer; 
likewise, there's no way to keep Java from collecting the Native peer when the 
Managed peer (the C# instance) is still alive.

Furthermore, 4.1 will be introducing a change in which IJavaObject implements 
IDisposable, so if you manually implement IJavaObject you'll probably be 
getting a compilation error out of it...

 - Jon

_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

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

Reply via email to