为了账号安全,请及时绑定邮箱和手机立即绑定

解决Xamarin.Android绑定第三方库时类型丢失的问题

标签:
Java

现象

今天在做一个第三方库绑定时,遇到如下情况:

webp

摘取其中一段代码如下:

/Users/huangboru/myfile/xamarin_workspace/version4/CrashEyeTestPlus/obj/Debug/generated/src/Com.Xsj.Crasheye.ActionError.cs(88,88): Error CS0234: The type or namespace name 'IInterfaceDataType' does not exist in the namespace 'Com.Xsj.Crasheye' (are you missing an assembly reference?) (CS0234) (CrashEyeTestPlus)

错误代码的意思是无法找到IInterfaceDataType类型。

解决过程

为了方便查看绑定的情况,我新建了一个Android Studio项目,添加这个第三方库,去看这个类型是什么,看到的情况如下:

package com.xsj.crasheye;import android.content.Context;interface InterfaceDataType {    String toJsonLine();    void send(Context var1, NetSender var2, boolean var3);    void send(NetSender var1, boolean var2);    void save(BaseDataSaver var1);
}

查阅官方文档,发现此类问题的可能情况有:

webp

webp

通过分析,我认为这个问题是第4种情况:Java允许一个公开类型去继承一个非公开的类型,而这在.Net中是不受支持的。由于绑定生成器无法生成对非公开类型的绑定,自然也就无法准确地绑定其公开的子类。为了解决这个问题,我们需要在Metadata.xml文件中将这个非公开的类型声明为公开类型。
在我的项目中,我添加的代码如下:

    <attr path="/api/package[@name='com.xsj.crasheye']/interface[@name='InterfaceDataType']" name="visibility">public</attr>
    <attr path="/api/package[@name='com.xsj.crasheye']/interface[@name='InterfaceExecutor']" name="visibility">public</attr>

不过问题并没有完全消除,还有一个error:

/Users/huangboru/myfile/xamarin_workspace/version4/CrashEyeTestPlus/obj/Debug/generated/src/Com.Xsj.Crasheye.ActionTransactionStop.cs(38,38): Error CS0234: The type or namespace name 'EnumTransactionStatus' does not exist in the namespace 'Com.Xsj.Crasheye' (are you missing an assembly reference?) (CS0234) (CrashEyeTestPlus)

我跟进到出现问题的地方:

    // Metadata.xml XPath field reference: path="/api/package[@name='com.xsj.crasheye']/class[@name='ActionTransactionStop']/field[@name='status']"
        [Register ("status")]        protected global::Com.Xsj.Crasheye.EnumTransactionStatus Status {
            get {                const string __id = "status.Lcom/xsj/crasheye/EnumTransactionStatus;";                var __v = _members.InstanceFields.GetObjectValue (__id, this);                return global::Java.Lang.Object.GetObject<global::Com.Xsj.Crasheye.EnumTransactionStatus> (__v.Handle, JniHandleOwnership.TransferLocalRef);
            }
            set {                const string __id = "status.Lcom/xsj/crasheye/EnumTransactionStatus;";

                IntPtr native_value = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value);                try {
                    _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value));
                } finally {                    global::Android.Runtime.JNIEnv.DeleteLocalRef (native_value);
                }
            }
        }

对方是一个非公开enum类型,我尝试像上面一样公开这个enum,但不可行。

观察代码可知,Xamarin在尝试绑定一个ActionTransactionStop的status字段,我到原生项目中查看这个字段:

public class ActionTransactionStop extends ActionTransaction implements InterfaceDataType {    protected EnumTransactionStatus status;
    .......
}

可知这是一个protected的字段,我们应该用不着也不应该访问这个字段,于是我直接添加了移除这个字段绑定的代码如下:

 <remove-node path="/api/package[@name='com.xsj.crasheye']/class[@name='ActionTransactionStop']/field[@name='status']" />

reBuild,ok!



作者:临岁之寒
链接:https://www.jianshu.com/p/36b3ef129f34


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
233
获赞与收藏
1008

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消