[mono-android] JNI Help Please
Jonathan Pryor
jonp at xamarin.com
Tue Jan 17 01:45:45 UTC 2012
On Jan 16, 2012, at 8:06 PM, digitalml wrote:
> I still have the issue of the callback though. What happens in the .java code is that when a hardware event occurs it fires the onReceiveMsgCardData() event.
My question from before remains the same: what code is calling onReceiveMsgCardData() and how does that code obtain the instance on which to call onReceiveMsgCardData()? That wasn't clear to me.
So let me assume something: the `uniMagReader` instance is responsible for calling onReceiveMsgCardData(), and the `uniMagReader` initialization is done within jni_helper.InitializeReader(). If that's the case, you could declare a Managed Callable Wrapper for `jni_helper` within C# (note: completely untested and uncompiled):
[Register ("MagHelper/jni_helper", DoNotGenerateAcw=true)]
class YourJniHelper : Java.Lang.Object {
public YourJniHelper ()
{
}
public YourJniHelper (IntPtr handle, JniHandleOwnership transfer)
: base (handle, transfer)
{
}
static IntPtr class_ref = JNIEnv.FindClass ("MagHelper/jni_helper");
protected override Type ThresholdType {
get {return typeof (YourJniHelper);}
}
protected override IntPtr ThresholdClass {
get {return class_ref;}
}
static IntPtr id_InitializeReader;
public void InitializeReader ()
{
if (id_InitializeReader == IntPtr.Zero)
id_InitializeReader = JNIEnv.GetMethodID(class_ref, "InitializeReader", "()V");
JNIEnv.CallVoidMethod (Handle, id_InitializeReader);
}
static IntPtr id_onReceiveMsgCardData;
[Register ("onReceiveMsgCardData", "(B[B)V", "Get_onReceiveMsgCardData_Handler")]
public virtual void OnReceiveMsgCardData (sbyte flagOfCardData, JavaArray<byte> cardData)
{
if (id_onReceiveMsgCardData == IntPtr.Zero)
id_onReceiveMsgCardData = JNIEnv.GetMethodID(class_ref, "onReceiveMsgCardData", "(B[B)V");
if (GetType () == ThresholdType) {
JNIEnv.CallVoidMethod (Handle, id_onReceiveMsgCardData,
new JValue (flagOfCardData),
new JValue (JNIEnv.ToJniHandle (cardData)));
return;
}
JNIenv.CallNonvirtualVoidMethod (Handle, ThresholdClass, id_onReceiveMsgCardData,
new JValue (flagOfCardData),
new JValue (JNIEnv.ToJniHandle (cardData)));
}
static Delegate cb_onReceiveMsgCardData;
static Delegate Get_onReceiveMsgCardData_Handler ()
{
if (cb_onReceiveMsgCardData == null)
cb_onReceiveMsgCardData = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, sbyte, IntPtr>) n_OnReceiveMsgCardData);
return cb_onReceiveMsgCardData;
}
static void n_OnReceiveMsgCardData (IntPtr jnienv, IntPtr lrefThis, byte flagOfCardData, IntPtr n_cardData)
{
YourJniHelper __this = Java.Lang.Object.GetObject<YourJniHelper>(lrefThis, JniHandleOwnership.DoNotTransfer);
using (var cardData = new JavaArray<byte>(n_cardData, JniHandleOwnership.DoNotTransfer))
__this. OnReceiveMsgCardData (flagOfCardData, cardData);
}
}
then subclass it:
class MyJniHelper : YourJniHelper {
public override void OnReceiveMsgCardData (sbyte flagOfCardData, IntPtr cardData)
{
/* ... */
}
}
then use it:
var helper = new MyJniHelper ();
helper.InitializeReader ();
You're not currently expected to understand the Managed Callable Wrapper; docs for that are in-progress, though you can follow the existing sample:
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
More information about the Monodroid
mailing list