我正在使用VS2015 Update3与当前/最新的Xamarin,我正在尝试创建一个绑定库来包装用Java编写的第三方SDK。我有一个C#/ .Net背景,到目前为止几乎没有Java经验。此SDK取决于其他3个项目,可以作为AAR或NuGet提供。
我能够为父AAR创建一个绑定库,使用一些MetaData.xml tweakery调整参数类型和返回类型并更正类访问器以满足其抽象基类,所有这些都是最初阻止生成的C#来自建筑的.Net Android绑定库。现在父绑定程序集已构建,但无法执行,因为它需要其他3个AAR依赖项。
需要的依赖关系("#"是以下帖子中提到的每个的别名):
在这种情况下,如果我需要创建一个绑定dll来包装依赖于3个其他AAR的父AAR:
我应该(A)创建4个绑定程序集 - 父绑定程序集Bind_AAR_1.dll,它依赖于Bind_AAR_2.dll,Bind_AAR_3.dll和Bind_AAR_4.dll吗?
或者,如果我(B)深入研究2,3和4个AAR文件并从每个文件中获取JAR文件,并使用' EmbeddedJar'将它们直接包含在Jars文件夹中的Bind_AAR_1.dll中。 (或其他属性/设置)?
或者,看到2,3和4实际上是通过NuGet提供的,我应该使用NuGet将它们引用到Bind_AAR_1项目吗?如果我使用NuGet引用/包含它们,那么AAR 1中的Javacode是否能够看到AAR'和4中的代码?
我已经尝试了各种方法(A),(B)和(C)的变化但没有运气,或导致工作导致更多的工作,这让我想知道什么是最好的/正确的这样做的方法。
在相关主题上,最佳做法是使用Metadata.xml文件从生成的生成的包装器API中明确删除您未直接计划在Xamarin项目中使用的所有内容(类等)吗?似乎限制接口可能是好的,也许还可以减少绑定dll的构建大小(以及可能的构建时间)。
任何帮助将不胜感激!
柯蒂斯
=============================================== ========================
4/11/2017 - 更新
非常高兴得到@_JonDouglas之类的投入!但是......仍然无法使这个SDK工作。
我已经尝试过这些方法A,B和C中的每一个,并且能够构建我的绑定项目(通过transforming / MetaData.xml完成操作)。第三方SDK被设计/记录为Java解决方案中的组件的一部分。根据供应商的指导文档,此解决方案将3个依赖项添加到其.gradle文件中,从而在整个Java解决方案中提供对这些项的引用。我没有Java历史,所以在这里展开它。
实际上,当我将SDK(单独使用或使用3种方法中的任何一种)与Visual Studio包装到Xamarin Android Binding Assembly中时,在运行时SDK会遇到ClassNotFound异常(由" Google Play证明)没找到。"在日志中)。从所需的Java依赖项中使用的类是以后期绑定的方式创建的,使用类名的字符串,如下所示:
try
{
Class.forName("com.google.android.gms.common.GooglePlayServicesUtil");
使用上述3种方法中的任何一种在Visual Studio中构建绑定程序集以包含依赖项(1个绑定中的1个AAR + 3个Nuget OR 1个AAR + 3个JAR或4个中的4个AAR)似乎并不重要。使用项目引用的绑定)。在运行时,SDK似乎没有看到它们。或许这是有意义的,它不会 - 在SDK本身中指向它们的没有.gradle(如csproj文件)?
//more code here
}
catch (ClassNotFoundException e)
{
Log.e("3rd Party SDK", "Google Play not found.");
}
我在想我需要做的是(更接近供应商的指令)创建一个Java解决方案,其中包含一个.gradle文件,该文件包含SDK以及Java项目中的3个依赖项,构建为创建一个AAR文件。然后,我相信我可以为最终包含的AAR创建一个Xamarin绑定程序集。然后我将在我的解决方案中添加对此绑定程序集的引用到我的.Andriod程序集并继续。
理论(尚未证实):[失败。请参阅下面的4/12更新。]将Java SDK +编码的依赖项(在.gradle中显式)包装在模块/库中,然后将其包装在Xamarin Android Binding库中。然后,我需要做的就是从这个包装器模块/库中找出我需要使用(并因此公开)的公共方法,添加这些公共方法并将调用转发给SDK。
大图:我尝试将其设计和编码为跨平台的Xamarin解决方案,但我正在使用特定于Android和IOS的SDK,这些SDK看起来都是应用程序/ UI的一部分经验(旨在做的不仅仅是处理与第三方的沟通)。这个UI方面尚未发挥作用,因为我还没有看到SDK功能。
=============================================== ========================
2017年4月4日 - 更新
理论(FAILED):将Java SDK +其编码依赖项(在.gradle中显式)包装在模块/库中,然后将其包装在Xamarin Android Binding库中。我们对此进行了编码,构建,部署和测试。我现在看到应用程序在运行时进入第一层Java代码,但未能找到任何低于该代码的引用代码(也称为依赖项)。包装器的代码运行正常,但运行时的包装器无法找到SDK的类,甚至也没有找到我们尝试通过包装器使用的简单Java测试组件。当我们单独为它创建一个绑定文件时,这相当于我们首先使用SDK的问题,并通过JAR或NuGet将其余部分引用到绑定程序集中。仍未找到较低级别的代码,只执行第一层java。仍在尝试提出解决方案。
=============================================== ========================
2017/4/13 - 更新
我取得了一些进展。向前迈出一步,也许是他们说的两步。
我现在意识到第三方SDK需要更多的Google Play服务,而不仅仅是两个依赖项。我反编译了明确提到的两个项目,并且命名类不在那里。我开始查看本地Android SDK位置(在Visual Studio中配置)并找到了“play-services-6.5.87.AAR'”。将它作为EmbeddedResourceJar包含在我的绑定程序集中最终得到了SDK代码,以找到上面代码中列出的特定类。
我在质疑上面描述的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
我尝试了很多不同的东西试图摆脱这个构建时错误,但没有任何运气。
如果我坚持使用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
还在挖......
答案 0 :(得分:4)
由于我的解决方案是跨平台,我有:
当我们达到目的时,各个.IOS项目/程序集将遵循这种命名模式。
清单
参考
组件(NuGet)
资产
构建时间需要额外的工作:
如上所述,当我构建MyApplication.Android.Binding时,它自己构建得很好。但是,当我在MyApplication.Android中引用它时,它生成了一个新的Java代码转换构建错误,该错误与特定类的范围不符合预期/要求。为了解决这个问题,我回到了Binding程序集的MetaData.xml文件,并选择从生成的Java代码接口中删除问题类,因为我没有计划调用或使用它。
提示:在Visual Studio中执行此操作(我已经找到)的最简单方法是在BindingAssembly项目上启用“显示所有文件”功能,然后查看obj \ Debug \ generated \ src \ folders对于问题类。找到后,单击它,生成的Java接口代码将生成XPath语句作为注释。这些是您使用MetaData.XML文件更改或删除问题类或方法所需的内容。
现在我需要做的就是在顶层编写我的跨平台代码(使用Dependency Inversion + Xamarin Forms内置DependencyService来在运行时访问每个SDK),我的应用程序应该不错!
希望这些发现对需要通过类似绑定方案工作的其他人有所帮助。
如果您确实在此处看到任何不正确的内容,或者您有任何想要添加的内容,请发表评论!
答案 1 :(得分:1)
您应该可以执行#3,只需参考这些现有的GPS /支持库绑定的预构建NuGet包。
请确保您使用绑定库所期望的确切版本,因为Google会一直移动类。
我的个人建议如下,按顺序排列(简单 - >难):
EmbeddedReferenceJar
/ ReferenceJar
.jar
或classes.jar
(如果有资源,请使用LibraryProjectZip
)
作为最佳做法,是的,您应该对不使用的项目使用<remove-node>
。但是,这主要用于首先不使用的代码生成错误时。无论如何,我都会保留这些物品,除非有很多方法你永远不会碰到所以你可以留意你的dexcount。
要获得进一步的帮助,您可以查看我的绑定指南:https://gist.github.com/JonDouglas/dda6d8ace7d071b0e8cb