Xamarin.Android Bindings - JNI invoker generates properties not fully implemented

Mantas Daškevičius 1 Reputation point
2022-03-23T14:46:54.687+00:00

I am making a Xamarin.Androiud binding class. One of a generated interfaces inherits from SDK interface ICheckable (android.widget.Checkable). For that it also generates an invoker. Problem with this invoker is that it does not implement one of the properties correctly - it misses "set" and generates a simple setter method that it cannot even generate a correct reference.

Here is a snippet of a generated code:

// Metadata.xml XPath interface reference: path="/api/package[@name='com.serenegiant.widget']/interface[@name='CheckableEx']"
    [Register ("com/serenegiant/widget/CheckableEx", "", "Com.Serenegiant.Widget.ICheckableExInvoker")]
    public partial interface ICheckableEx : global::Android.Widget.ICheckable {
    }

    [global::Android.Runtime.Register ("com/serenegiant/widget/CheckableEx", DoNotGenerateAcw=true)]
    internal partial class ICheckableExInvoker : global::Java.Lang.Object, ICheckableEx {

        <...>

        static Delegate cb_isChecked;
#pragma warning disable 0169
        static Delegate GetGetCheckedHandler ()
        {
            if (cb_isChecked == null)
                cb_isChecked = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_Z) n_GetChecked);
            return cb_isChecked;
        }

        static bool n_GetChecked (IntPtr jnienv, IntPtr native__this)
        {
            var __this = global::Java.Lang.Object.GetObject<global::Com.Serenegiant.Widget.ICheckableEx> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            return __this.Checked;
        }
#pragma warning restore 0169

        IntPtr id_isChecked;
        //PROPERTY THAT IS NOT IMPLEMENTED CORECTLY
        public unsafe global::System.Boolean Checked {
            get {
                if (id_isChecked == IntPtr.Zero)
                    id_isChecked = JNIEnv.GetMethodID (class_ref, "isChecked", "()Z");
                return JNIEnv.CallBooleanMethod (((global::Java.Lang.Object) this).Handle, id_isChecked);
            }
        }

        static Delegate cb_setChecked_Z;
#pragma warning disable 0169
        static Delegate GetSetChecked_ZHandler ()
        {
            if (cb_setChecked_Z == null)
                cb_setChecked_Z = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPZ_V) n_SetChecked_Z);
            return cb_setChecked_Z;
        }

        static void n_SetChecked_Z (IntPtr jnienv, IntPtr native__this, bool value)
        {
            var __this = global::Java.Lang.Object.GetObject<global::Com.Serenegiant.Widget.ICheckableEx> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            __this.SetChecked (value);
        }
#pragma warning restore 0169

        IntPtr id_setChecked_Z;
        public unsafe void SetChecked (bool value)
        {
            if (id_setChecked_Z == IntPtr.Zero)
                id_setChecked_Z = JNIEnv.GetMethodID (class_ref, "setChecked", "(Z)V");
            JValue* __args = stackalloc JValue [1];
            __args [0] = new JValue (value);
            JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_setChecked_Z, __args);
        }

        <...>

    }

Here is a snipped of ICheckable :

namespace Android.Widget
{
    [Register("android/widget/Checkable", "", "Android.Widget.ICheckableInvoker")]
    public interface ICheckable : IJavaObject, IDisposable, IJavaPeerable
    {
        bool Checked { get; set; }

        [Register("toggle", "()V", "GetToggleHandler:Android.Widget.ICheckableInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
        void Toggle();
    }
}

Snippet from api.xml

<interface abstract="true" deprecated="not deprecated" final="false" name="CheckableEx" static="false" visibility="public" jni-signature="Lcom/serenegiant/widget/CheckableEx;">
  <implements name="android.widget.Checkable" name-generic-aware="android.widget.Checkable" jni-type="Landroid/widget/Checkable;">
  </implements>
  <field deprecated="not deprecated" final="true" name="CHECKED_STATE_SET" jni-signature="[I" static="true" transient="false" type="int[]" type-generic-aware="int[]" visibility="public" volatile="false">
  </field>
</interface>

Other problems like names, access modifiers, types etc (using metadata.xml) is somewhat clear but how to deal with not fully generated properties?

Developer technologies | .NET | Xamarin
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.