【问题标题】:Xamarin.Android binding defining Getter/Setter Methods using EnumMethods.xml for interfaceXamarin.Android 绑定使用 EnumMethods.xml 为接口定义 Getter/Setter 方法
【发布时间】:2016-11-03 17:33:24
【问题描述】:

EnumMethods.xml 有问题。我将它用于某些界面,this 映射按预期工作。但是,如果我有另一个扩展原始接口的接口,则映射不起作用,我会收到以下错误:

"Cannot implicitly convert type 'int' to 'MyEnum'. An explicit conversion exists (are you missing a cast?)"

"Cannot implicitly convert type 'MyEnum' to 'int'. An explicit conversion exists (are you missing a cast?)"

有什么建议吗?

映射如下所示:

<mapping jni-interface="path/IView">
  <method jni-name="getSmth" parameter="return" clr-enum-type="MyEnum" />
  <method jni-name="setSmth" parameter="param" clr-enum-type="MyEnum" />
</mapping>

编辑

澄清一下。假设第二个称为 IViewInheritor。所以上面的错误在 IViewInheritorInvoker 类里面。 我也有这个类的映射。

<mapping jni-interface="path/IViewInheritor">
  <method jni-name="getSmth" parameter="return" clr-enum-type="MyEnum" />
  <method jni-name="setSmth" parameter="param" clr-enum-type="MyEnum" />
</mapping>

attached bindings project

【问题讨论】:

  • 尝试为另一个映射指定 jni-interface 而不是 jni-class
  • 他们都使用了jni-interface。刚刚更新了问题
  • 您是否为有问题的接口添加了一个额外的?
  • 是的,我确实为两个接口添加了它。我唯一没有提到的是这些接口在不同的项目/库中
  • 如果您有绑定项目的副本,可以上传并附加到您的问题中,我可以看看。

标签: android xamarin xamarin.android


【解决方案1】:

首先我们看一下api.xmlCore.IView的定义:

<interface abstract="true" deprecated="not deprecated" final="false" name="IView" static="false" visibility="public">
<method abstract="true" deprecated="not deprecated" final="false" name="getVisibility" native="false" return="int" static="false" synchronized="false" visibility="public">
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="setVisibility" native="false" return="void" static="false" synchronized="false" visibility="public">
<parameter name="p0" type="int">
</parameter>
</method>
</interface>

好的,我们看到了确切的参数名称和返回类型。

1>BINDINGSGENERATOR : warning : [Interface] dom.core.IView in [Method] void setVisibility(int p0) has 'unnamed' parameters

1>BINDINGSGENERATOR : warning BG8A04: <attr path="/api/package[@name='dom.core']/interface[@name='IView']/method[@name='setVisibility']/parameter[@name='visibility']"/> matched no nodes.

所以我们需要在Core项目的EnumMethods.xml中将这里的参数重命名为p0

那么我们就可以看出区别了:

IView

static Delegate cb_getVisibility;
#pragma warning disable 0169
        static Delegate GetGetVisibilityHandler ()
        {
            if (cb_getVisibility == null)
                cb_getVisibility = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, int>) n_GetVisibility);
            return cb_getVisibility;
        }

        static int n_GetVisibility (IntPtr jnienv, IntPtr native__this)
        {
            global::Dom.Core.IView __this = global::Java.Lang.Object.GetObject<global::Dom.Core.IView> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            return (int) __this.Visibility;
        }
#pragma warning restore 0169

        static Delegate cb_setVisibility_I;
#pragma warning disable 0169
        static Delegate GetSetVisibility_IHandler ()
        {
            if (cb_setVisibility_I == null)
                cb_setVisibility_I = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, int>) n_SetVisibility_I);
            return cb_setVisibility_I;
        }

        static void n_SetVisibility_I (IntPtr jnienv, IntPtr native__this, int native_p0)
        {
            global::Dom.Core.IView __this = global::Java.Lang.Object.GetObject<global::Dom.Core.IView> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            global::Android.Views.ViewStates p0 = (global::Android.Views.ViewStates) native_p0;
            __this.Visibility = p0;
        }
#pragma warning restore 0169

        IntPtr id_getVisibility;
        IntPtr id_setVisibility_I;
        public unsafe global::Android.Views.ViewStates Visibility {
            get {
                if (id_getVisibility == IntPtr.Zero)
                    id_getVisibility = JNIEnv.GetMethodID (class_ref, "getVisibility", "()I");
                return (global::Android.Views.ViewStates) JNIEnv.CallIntMethod (((global::Java.Lang.Object) this).Handle, id_getVisibility);
            }
            set {
                if (id_setVisibility_I == IntPtr.Zero)
                    id_setVisibility_I = JNIEnv.GetMethodID (class_ref, "setVisibility", "(I)V");
                JValue* __args = stackalloc JValue [1];
                __args [0] = new JValue ((int) value);
                JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_setVisibility_I, __args);
            }
        }

ICustomView

static Delegate cb_getVisibility;
#pragma warning disable 0169
        static Delegate GetGetVisibilityHandler ()
        {
            if (cb_getVisibility == null)
                cb_getVisibility = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, int>) n_GetVisibility);
            return cb_getVisibility;
        }

        static int n_GetVisibility (IntPtr jnienv, IntPtr native__this)
        {
            global::Dom.Common.ICustomView __this = global::Java.Lang.Object.GetObject<global::Dom.Common.ICustomView> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            return __this.Visibility;
        }
#pragma warning restore 0169

        static Delegate cb_setVisibility_I;
#pragma warning disable 0169
        static Delegate GetSetVisibility_IHandler ()
        {
            if (cb_setVisibility_I == null)
                cb_setVisibility_I = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, int>) n_SetVisibility_I);
            return cb_setVisibility_I;
        }

        static void n_SetVisibility_I (IntPtr jnienv, IntPtr native__this, int native_value)
        {
            global::Dom.Common.ICustomView __this = global::Java.Lang.Object.GetObject<global::Dom.Common.ICustomView> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            global::Android.Views.ViewStates value = (global::Android.Views.ViewStates) native_value;
            __this.Visibility = value;
        }
#pragma warning restore 0169

        IntPtr id_getVisibility;
        IntPtr id_setVisibility_I;
        public unsafe global::Android.Views.ViewStates Visibility {
            get {
                if (id_getVisibility == IntPtr.Zero)
                    id_getVisibility = JNIEnv.GetMethodID (class_ref, "getVisibility", "()I");
                return JNIEnv.CallIntMethod (((global::Java.Lang.Object) this).Handle, id_getVisibility);
            }
            set {
                if (id_setVisibility_I == IntPtr.Zero)
                    id_setVisibility_I = JNIEnv.GetMethodID (class_ref, "setVisibility", "(I)V");
                JValue* __args = stackalloc JValue [1];
                __args [0] = new JValue ((int) value);
                JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_setVisibility_I, __args);
            }
        }

我们看到ICustomView 中缺少几个演员表:

(global::Android.Views.ViewStates) and (int)

特别是在n_SetVisibility_In_GetVisibility 方法中。

【讨论】:

  • 哦,我看到那个参数了,谢谢。但现在出现另一个警告:“[方法] void setVisibility(int p0) 中的[接口] dom.core.IView 具有'未命名'参数”这是因为 p0 吗?关于演员表,有没有办法省略它?我的意思是在生成该代码后手动投射将是皮塔饼。
  • 有什么办法可以解决这些铸造问题吗?
猜你喜欢
  • 1970-01-01
  • 2017-08-23
  • 2012-10-02
  • 2014-09-06
  • 1970-01-01
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多