Xamarin Android java.lang.InstantiationException:java.lang.Class 没有零参数构造函数

Posted

技术标签:

【中文标题】Xamarin Android java.lang.InstantiationException:java.lang.Class 没有零参数构造函数【英文标题】:Xamarin Android java.lang.InstantiationException: java.lang.Class has no zero argument constructor 【发布时间】:2019-12-17 10:11:57 【问题描述】:

我正在尝试在 xamarin 中实现 java 库。为此,我创建了一个 java 绑定库并将 dll 引用到我的 xamarin.android 项目中。基本上 JBL 生成的代码如下所示。如您所见,它没有带 0 个参数的构造函数。

public abstract class SAAgent : Service


        [Register(".ctor", "(Ljava/lang/String;)V", "")]
        protected SAAgent(string p0);
        protected SAAgent(IntPtr javaReference, JniHandleOwnership transfer);
        [Register(".ctor", "(Ljava/lang/String;Ljava/lang/Class;)V", "")]
        protected SAAgent(string p0, Class p1);

我实现了一个继承这个生成的 SAAgent 类的类。

 [Service(Exported = true, Name = "WearCompanion.Droid.ProviderService")]
    public class ProviderService : SAAgent 
       

        public ProviderService() : base("ProviderService", SASOCKET_CLASS)
        

        

当我执行代码时,我收到一个异常,告诉我

Java.Lang.RuntimeException Message=无法实例化服务 WearCompanion.Droid.ProviderService: java.lang.InstantiationException: java.lang.Class 没有零 参数构造函数

所以它期望我有 0 参数构造函数。 Samsung Tizen 网站上有一个示例,他们的 java 示例如下所示

public class ProviderService extends SAAgent 
    private static final String TAG = "HelloAccessory(P)";
    private static final Class<ServiceConnection> SASOCKET_CLASS = ServiceConnection.class;

    public ProviderService() 
        super(TAG, SASOCKET_CLASS);
    

但是当我查看我的 xamarin.android 项目的 obj 文件夹并找到生成的 ProviderClass.java 文件时。如下图,

public class ProviderService
    extends com.samsung.android.sdk.accessory.SAAgent
    implements
        mono.android.IGCUserPeer



    public ProviderService (java.lang.String p0, java.lang.Class p1)
    
        super (p0, p1);
        if (getClass () == ProviderService.class)
            mono.android.TypeManager.Activate ("WearCompanion.Droid.ProviderService, WearCompanion.Android", "System.String, mscorlib:Java.Lang.Class, Mono.Android", this, new java.lang.Object[]  p0, p1 );
    

我不明白如何让 xamarin 使用 0 构造函数从 c# 生成 java 类? 那是java绑定问题吗?

PS,我已经反编译了 jar 来查看 SAAgent java 实现,它与 C# 相同。所以java绑定库做了正确的工作。我不确定是否应该自己手动添加无参数构造函数?

【问题讨论】:

根据你的代码,SAAgent没有0参数构造函数,ProviderService类继承了SAAgent,所以应该public ProviderService(string p0, Class p1) : base(p0, p1) @CherryBu 没错。原始 Java SAAgent 类也没有 0 参数构造函数,但继承的类有它,如第三段代码所示。所以错误也适用于具有 0 参数的 ProviderService。我的 c# 代码由 Xamarin.Android 转换为第 4 个代码段,但它应该转换为上面的第 3 个代码段。这是我的问题。也许这是 xamarin 中的一个错误,或者我应该处理从 c# 到 java 的东西 您可以手动添加参数构造函数,看看是否有效。 @CherryBu 它实际上期望一个零参数。所以我应该能够在 c# 中将其定义为 public ProviderService() 但是如果我尝试这样做会出现构建错误,因为它说 base 不包含任何零参数,但在运行时它会抱怨 ProviderService 没有零参数构造函数。因为 Xamarin 像我的问题一样生成 java 类。它应该产生一个类 public ProviderService() super(TAG, SASOCKET_CLASS);像这样。这两个在 java 中有明显的区别,但在 C# 中没有 【参考方案1】:

我终于找到了解决方案。 Xamarin 实际上在他们的documentation 中有关于缺少构造函数的信息。正如所解释的,它应该使用一个 Export 属性。因此,如果我如下更改我的 C# 类构造函数。它使用零参数构造函数按预期生成精确的 java 类。

 [Export(SuperArgumentsString = "\"ProviderService\", ProviderService_ProviderServiceSocket.class")]
        public ProviderService() : base("ProviderService", SASOCKET_CLASS)
        

        

【讨论】:

以上是关于Xamarin Android java.lang.InstantiationException:java.lang.Class 没有零参数构造函数的主要内容,如果未能解决你的问题,请参考以下文章

xamarin android如何将Java.Lang.Object类型转成C#类型

Java.Lang.ClassNotFoundException WebAuthenticatorActivity

Xamarin.Forms Android PopupMenu问题二

Xamarin 使用 CallRedirectionService 引发 Java.Lang.ClassNotFoundException

Xamarin Android - 找不到.so文件

FusedLocation GoogleApi - 侦听器不得为空 (Xamarin.Android)