【发布时间】:2017-04-06 19:34:52
【问题描述】:
我正在使用带有当前/最新 Xamarin 的 VS2015 Update3,并且正在尝试创建一个绑定库来包装用 Java 编写的第 3 方 SDK。我有 C#/.Net 背景,到目前为止几乎没有 Java 经验。此 SDK 依赖于其他 3 个项目,可作为 AAR 或通过 NuGet 获得。
我能够为父 AAR 创建一个绑定库,使用一些 MetaData.xml 调整来调整参数类型和返回类型并更正类访问器以满足其抽象基类,所有这些最初都阻止了生成的 C# .Net Android 绑定库来自构建。现在父绑定程序集已构建,但无法执行,因为它需要其他 3 个 AAR 依赖项。
需要依赖项(“#”是下面帖子中提到的每个依赖项的别名):
- “2”-> com.android.support:support-v4:25.1.1
- “3”-> com.google.android.gms:play-services-location:10.2.0
- “4”-> com.google.android.gms:play-services-gcm:10.2.0
在这种情况下,如果我需要创建一个绑定 dll 来包装依赖于其他 3 个 AAR 的父 AAR:
我是否应该 (A) 创建 4 个绑定程序集 - 一个依赖于 Bind_AAR_2.dll、Bind_AAR_3.dll 和 Bind_AAR_4.dll 的父绑定程序集 Bind_AAR_1.dll?
或者,我是否应该 (B) 深入研究 2、3 和 4 个 AAR 文件并从每个文件中获取 JAR 文件,然后使用“EmbeddedJar”(或其他属性/设置)?
或者,看到 2、3 和 4 实际上可以通过 NuGet 获得,我是否应该 (C) 使用 NuGet 将它们引用到 Bind_AAR_1 项目中?如果我使用 NuGet 引用/包含它们,AAR 1 中的 Javacode 是否能够看到 AAR 2、3 和 4 中的代码?
我尝试了每种方法 (A)、(B) 和 (C) 的变体,但没有运气,或者结果工作导致更多工作,这让我想知道什么是最好/正确的方法这样做。
在相关主题上,使用 Metadata.xml 文件从生成的包装 API 中显式删除您不打算在 Xamarin 项目中直接使用的所有内容(类等)是否是最佳做法?似乎限制接口可能会很好,也可能会减少绑定 dll 的构建大小(可能还有构建时间)。
任何帮助将不胜感激!
柯蒂斯
================================================ =========================
2017 年 4 月 11 日 - 更新
很高兴收到@_JonDouglas 之类的意见!但是...仍然无法让这个 SDK 工作。
我已经尝试了这些方法 A、B 和 C 中的每一个,并且能够构建我的绑定项目(通过转换/MetaData.xml 完成操作)。第 3 方 SDK 被设计/记录为 Java 解决方案中的一部分/组件。根据供应商的说明文档,此解决方案会将 3 个依赖项添加到其 .gradle 文件中,从而在整个 Java 解决方案中提供对这些项目的引用。我没有 Java 历史记录,所以在这里讨论一下。
事实上,当我使用 Visual Studio 将 SDK(单独或使用这 3 种方法中的任何一种的依赖项)包装到 Xamarin Android 绑定程序集中时,SDK 在运行时会遇到 ClassNotFound 异常(由“Google Play not found. “在日志中)。从所需的 Java 依赖项中使用的类是使用类名的名称字符串以后期绑定方式创建的,如下所示:
try
{
Class.forName("com.google.android.gms.common.GooglePlayServicesUtil");
我如何使用上述 3 种方法中的任何一种在 Visual Studio 中构建绑定程序集以包含依赖项(1 AAR + 3 Nuget OR 1 AAR + 3 Jars in 1 binding OR 4 AARs in 4 binding using项目参考)。在运行时,SDK 似乎看不到它们。也许这是有道理的,它不会 - 在 SDK 本身中没有指向它们的 .gradle(如 csproj 文件)?
//more code here
}
catch (ClassNotFoundException e)
{
Log.e("3rd Party SDK", "Google Play not found.");
}
我在想我需要做的是(更接近供应商的说明)创建一个包含 .gradle 文件的 Java 解决方案,其中包括 SDK 以及 Java 项目中的 3 个依赖项,构建以创建 AAR 文件.然后,我相信我可以为生成的包含 AAR 创建一个 Xamarin 绑定程序集。然后,我会在我的解决方案中将对此绑定程序集的引用添加到我的 .Andriod 程序集并继续。
理论(尚待证明):[失败。请参阅下面的 4/12 更新。] 将 Java SDK + 其编码依赖项(在 .gradle 中显式)包装在模块/库中,然后将其包装在 Xamarin Android 绑定库中。然后我需要做的就是从这个包装模块/库中找出我需要使用(并因此公开)哪些公共方法,添加这些公共方法并将调用转发到 SDK。
大图:我正在尝试将其设计和编码为跨平台 Xamarin 解决方案,但我正在使用特定于 Android 和特定于 IOS 的 SDK,它们似乎都旨在成为应用程序/UI 体验的一部分(旨在做的不仅仅是处理与第 3 方的通信)。这个 UI 方面还没有发挥出来,因为我还没有看到任何 SDK 功能。
================================================ =========================
2017 年 4 月 12 日 - 更新
理论(失败):将 Java SDK + 其编码依赖项(在 .gradle 中显式)包装在模块/库中,然后将其包装在 Xamarin Android 绑定库中。我们对此进行了编码、构建、部署和测试。我现在看到应用程序在运行时进入了第一层 Java 代码,但找不到任何低于该层的引用代码(也称为依赖项)。包装器的代码运行良好,但包装器在运行时找不到 SDK 的类,甚至找不到我们试图通过包装器使用的简单 Java 测试组件。这相当于我们最初使用 SDK 时遇到的问题,当时我们只是为它单独创建了一个绑定文件,然后通过 JAR 或通过 NuGet 将其余部分引用到绑定程序集中。下层代码还是没有找到,只执行了第一层java。仍在尝试提出解决方案。
================================================ =========================
2017 年 4 月 13 日 - 更新
我已经取得了一些进展。正如他们所说,向前一步,也许后退两步。
我现在意识到第 3 方 SDK 需要更多的 Google Play 服务,而不仅仅是两个依赖项。我对明确提到的两个项目进行了反编译,命名类不在其中。我开始查看本地 Android SDK 位置(在 Visual Studio 中配置)并找到“play-services-6.5.87.AAR”。将它作为 EmbeddedResourceJar 包含在我的绑定程序集中最终得到了 SDK 代码,以找到上面代码中列出的特定类。
使用 NuGet
我质疑上述 Java 包装器的价值,因为依赖项所需的一切现在都包含在 EmbeddedReferenceJar 中。似乎我应该直接绑定 SDK AAR(不添加 Java 包装层)。我正在重新考虑这一点,并尝试在 JARS 文件夹中创建指向 SDK AAR 的绑定程序集,然后使用 NuGet 包含 Google Play 服务。
继续,(使用 NuGet 引用 Google Play 服务)我现在收到此错误:
No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version'). {project name} {project path}\AndroidManifest.xml
我已经尝试了很多不同的方法来试图摆脱这个构建时错误,但没有任何运气。
不使用 NuGet
如果我坚持使用 Google 的“play-services-6.5.87.AAR”中的 JAR 文件作为 EmbeddedResourceJar,我不会收到构建错误,但会收到 SDK 无法解决的运行时错误找到所需的 Android 清单设置。如果您有这样安排的项目,我对使用哪个 Android Manifest 是否正确?
XXX PCL Project
--> XXX.Android project <-- My guess is that this is where the AndroidManifest.XML file is located that will be used....?
----> XXX.Android.AARBinding project
------> JARS folder --> 3pVendorSDK.AAR
还在挖....
【问题讨论】:
标签: c# .net xamarin xamarin.android aar