On Jan 13, 2012, at 8:05 PM, digitalml wrote:
> All JNI examples I've found either return an activity or use static methods
> and mine is not static and not really an activity I want to show on the
> screen.
The SanityTests sample has a more complete example of JNI use:
https://github.com/xamarin/monodroid-samples/tree/master/SanityTests
https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Adder.java
https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Hello.cs#L514
> Here is the .java file im using, it compiles fine...
> ---------------------------------------------------------
> import IDTech.MSR.uniMag.uniMagReader;
> import IDTech.MSR.uniMag.uniMagReaderMsg;
> import android.app.Activity;
>
> public class jni_helper extends Activity implements uniMagReaderMsg {
Why does your class extend Activity if you don't want to show it on the screen?
> private jni_helper()
> {
> }
...and how are you supposed to obtain an instance of `jni_helper` when the
constructor is static?
> public void InitializeReader()
> {
> if(myUniMagReader == null)
> myUniMagReader = new uniMagReader(this, this);
Is it fair to assume that `uniMagReader` is what calls the
onReceiveMsgCardData() method?
> I'd like to be able to call the InitializeReader() method
...
> And here is my .Net helper class to call the JNI. It errors at the
> JNIEnv.CallVoidMethod()
> private static IntPtr _helperClass =
> JNIEnv.FindClass("Stations/MagHelper/jni_helper");
> public static void InitializeReader()
> {
> IntPtr methodId = JNIEnv.GetMethodID(_helperClass,
> "InitializeReader", "()V");
> if (null != methodId)
> JNIEnv.CallVoidMethod(_helperClass, methodId);
CallVoidMethod() requires an instance handle, and you're providing a class
handle, hence the error. You need to obtain an instance. However, given that
the constructor is private, and that that there are no static methods on the
class, I'm not sure how you're supposed to obtain an instance.
Assuming that you can actually invoke a private constructor through JNI (which
I've never tried), you could do:
IntPtr ctor = JNIEnv.GetMethodID(_helperClass, "<init>", "()V");
IntPtr instance = JNIEnv.NewObject(_helperClass, ctor);
JNIEnv.CallVoidMethod(instance, methodid /* for InitializeReader */);
> the SwipeCard() method
SwipeCard is ~identical to InitializeReader(): obtain an instance "somehow",
then invoke the method:
IntPtr instance = ...; // same as above?
IntPtr jni_helper_SwipeCard = JNIEnv.GetMethodID(_helperClass,
"SwipeCard", "()V");
IntPtr.CallVoidMethod(instance, jni_helper_SwipeCard);
> listen for the callback onReceiveMsgCardData()
This is trickier, as I don't really understand your Java code. What code is
calling onReceiveMsgCardData()? How is the instance registered with that code?
I have to assume that `myUniMagReader.registerListen()` causes the
`uniMagReader` instance to start invoking the onReceiveMsgCardData() method,
but there is no apparent way to alter what object it registers -- it uses
`this`, but (as mentioned above) there's no way to instantiate `jni_helper`
instances. There's certainly no way to subclass `jni_helper`, as the
constructor is private, and the only mechanism I can think of to "listen for
the callback onReceiveMsgCardData()" is to subclass `jni_helper` and override
that method, and I can't fathom how any of that would work here.
`jni_helper` aside, you CAN subclass Java types in C# and override their
virtual methods, it just takes more work. We're working on documentation to
explain this, but we do have a sample in the meantime, see:
The base Java class:
https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Adder.java
The C# glue code for inheritance:
https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs
The C# subclass of the Java type:
https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs#L155
- Jon
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid