绑定 Java 库Binding a Java Library

Android 社区有很多您可能想在您的应用程序; 若要使用的 Java 库本指南介绍如何将 Java 库合并到 Xamarin.Android 应用程序,通过创建绑定库。The Android community has many Java libraries that you may want to use in your app; this guide explains how to incorporate Java libraries into your Xamarin.Android application by creating a Bindings Library.

概述Overview

适用于 Android 的第三方库生态系统是巨大的。The third-party library ecosystem for Android is massive. 因此,通常最好使用比创建一个新的现有 Android 库。Because of this, it frequently makes sense to use an existing Android library than to create a new one. Xamarin.Android 提供两种方法来使用这些库:Xamarin.Android offers two ways to use these libraries:

  • 创建绑定库自动包装与库C#包装器,因此可以调用 Java 代码通过C#的调用。Create a Bindings Library that automatically wraps the library with C# wrappers so you can invoke Java code via C# calls.

  • 使用Java 本机接口(JNI) 来直接调用 Java 库代码中的调用。Use the Java Native Interface (JNI) to invoke calls in Java library code directly. JNI 是一个编程框架,允许调用并由本机应用程序或库调用的 Java 代码。JNI is a programming framework that enables Java code to call and be called by native applications or libraries.

本指南将介绍第一个选项: 如何创建绑定库,将一个或多个现有的 Java 库包装成可以在应用程序中链接到程序集。This guide explains the first option: how to create a Bindings Library that wraps one or more existing Java libraries into an assembly that you can link to in your application. 有关使用 JNI 的详细信息,请参阅使用 JNIFor more information about using JNI, see Working with JNI.

Xamarin.Android 使用来实现绑定托管可调用包装器(MCW)。Xamarin.Android implements bindings by using Managed Callable Wrappers (MCW). MCW 是托管的代码需要调用 Java 代码时使用的 JNI 桥梁。MCW is a JNI bridge that is used when managed code needs to invoke Java code. 子类化 Java 类型和重写虚拟方法在 Java 类型,托管的可调用包装器还提供支持。Managed callable wrappers also provide support for subclassing Java types and for overriding virtual methods on Java types. 同样,只要 Android 运行时 (艺术) 代码想要调用托管的代码,它会通过已知为 Android 可调用包装器 (ACW) 的另一个 JNI 桥。Likewise, whenever Android runtime (ART) code wishes to invoke managed code, it does so via another JNI bridge known as Android Callable Wrappers (ACW). 体系结构下图中所示:This architecture is illustrated in the following diagram:

Android JNI 桥体系结构Android JNI bridge architecture

绑定库是包含管理可调用包装器的 Java 类型的程序集。A Bindings Library is an assembly containing Managed Callable Wrappers for Java types. 例如,下面是一个 Java 类型, MyClass,我们想要在绑定库自动换行:For example, here is a Java type, MyClass, that we want to wrap in a Bindings Library:

package com.xamarin.mycode;

public class MyClass
{
    public String myMethod (int i) { ... }
}

我们生成一个绑定库,用于以后 .jar ,其中包含MyClass,我们可以实例化它并从其上调用方法C#:After we generate a Bindings Library for the .jar that contains MyClass, we can instantiate it and call methods on it from C#:

var instance = new MyClass ();

string result = instance.MyMethod (42);

若要创建此绑定库,请使用 Xamarin.Android Java 绑定库模板。To create this Bindings Library, you use the Xamarin.Android Java Bindings Library template. 生成的绑定项目与 MCW 类创建.NET 程序集 .jar文件,并适用于 Android 库项目中嵌入资源。The resulting binding project creates a .NET assembly with the MCW classes, .jar file(s), and resources for Android Library projects embedded in it. 您也可以为 Android 存档创建绑定库 (。AAR) 文件和 Eclipse Android 库项目。You can also create Bindings Libraries for Android Archive (.AAR) files and Eclipse Android Library projects. 通过引用生成的绑定库 DLL 程序集,您可以在 Xamarin.Android 项目中重用现有的 Java 库。By referencing the resulting Bindings Library DLL assembly, you can reuse an existing Java library in your Xamarin.Android project.

当您在绑定库中引用的类型时,必须使用绑定库的命名空间。When you reference types in your Binding Library, you must use the namespace of your binding library. 通常情况下,添加using顶部的指令在C#源文件,它是.NET 命名空间版本的 Java 包名称。Typically, you add a using directive at the top of your C# source files that is the .NET namespace version of the Java package name. 例如,如果您所绑定的 Java 包名称 .jar所示:For example, if the Java package name for your bound .jar is the following:

com.company.package

然后可使以下using顶部的语句在C#源文件访问绑定中的类型 .jar文件:Then you would put the following using statement at the top of your C# source files to access types in the bound .jar file:

using Com.Company.Package;

绑定现有 Android 库时,必须要记住以下几点:When binding an existing Android library, it is necessary to keep the following points in mind:

  • 是否有任何库的外部依赖关系?Are there any external dependencies for the library? – 必须为 Xamarin.Android 项目中包含所需的 Android 库的任何 Java 依赖项ReferenceJar或是EmbeddedReferenceJar– Any Java dependencies required by the Android library must be included in the Xamarin.Android project as a ReferenceJar or as an EmbeddedReferenceJar. 必须将任何本机程序集添加到作为绑定项目EmbeddedNativeLibraryAny native assemblies must be added to the binding project as an EmbeddedNativeLibrary.

  • 哪个版本的 Android API does Android 库目标?What version of the Android API does the Android library target? – 不能以"降级"的 Android API 级别;确保,Xamarin.Android 绑定项目面向的相同的 API 级别 (或更高) 为 Android 库。– It is not possible to "downgrade" the Android API level; ensure that the Xamarin.Android binding project is targeting the same API level (or higher) as the Android library.

  • 哪些版本的 JDK 用于编译库?What version of the JDK was used to compile the library? – 如果使用不同版本的 JDK 比在使用 xamarin.android 生成 Android 库,可能会发生绑定错误。– Binding errors may occur if the Android library was built with a different version of JDK than in use by Xamarin.Android. 如果可能,请重新编译使用相同的 Xamarin.Android 安装使用的 jdk 版本的 Android 库。If possible, recompile the Android library using the same version of the JDK that is used by your installation of Xamarin.Android.

生成操作Build Actions

创建绑定库,当您设置生成操作.jar或。AAR 文件合并到绑定库项目–每个生成操作确定如何 .jar或。将嵌入到 (或引用) AAR 文件绑定库。When you create a Bindings Library, you set build actions on the .jar or .AAR files that you incorporate into your Bindings Library project – each build action determines how the .jar or .AAR file will be embedded into (or referenced by) your Bindings Library. 以下列表总结了这些生成操作:The following list summarizes these build actions:

  • EmbeddedJar – 将嵌入 .jar到作为嵌入资源生成的绑定库 DLL。EmbeddedJar – Embeds the .jar into the resulting Bindings Library DLL as an embedded resource. 这是最简单和大多数常用的生成操作。This is the simplest and most commonly-used build action. 如果你想使用此选项 .jar自动编译成字节代码并打包到绑定库。Use this option when you want the .jar automatically compiled into byte code and packaged into the Bindings Library.

  • InputJar – 不会嵌入 .jar到生成的绑定库。DLL。InputJar – Does not embed the .jar into the resulting Bindings Library .DLL. 绑定库。DLL 会对此有依赖关系 .jar在运行时。Your Bindings Library .DLL will have a dependency on this .jar at runtime. 使用此选项,如果不希望包括 .jar绑定库 (例如,出于许可原因) 中。Use this option when you do not want to include the .jar in your Bindings Library (for example, for licensing reasons). 如果使用此选项,则必须确保输入 .jar可在运行您的应用程序的设备上。If you use this option, you must ensure that the input .jar is available on the device that runs your app.

  • LibraryProjectZip – 将嵌入。AAR 文件到生成的绑定库。DLL。LibraryProjectZip – Embeds an .AAR file into the resulting Bindings Library .DLL. 它类似于 EmbeddedJar,只不过在绑定中,可以访问资源 (以及代码)。AAR 文件。This is similar to EmbeddedJar, except that you can access resources (as well as code) in the bound .AAR file. 如果你想要嵌入使用此选项。AAR 到绑定库。Use this option when you want to embed an .AAR into your Bindings Library.

  • ReferenceJar – 指定的引用 .jar: 一个引用 .jar.jar到绑定的其中一个 .jar或。AAR 文件取决于。ReferenceJar – Specifies a reference .jar: a reference .jar is a .jar that one of your bound .jar or .AAR files depends on. 此引用 .jar仅用于满足编译时依赖项。This reference .jar is used only to satisfy compile-time dependencies. 当使用此生成操作,C#绑定不会创建引用 .jar并且它不嵌入在生成的绑定库中。DLL。When you use this build action, C# bindings are not created for the reference .jar and it is not embedded in the resulting Bindings Library .DLL. 使用此选项时将使绑定库参考 .jar但尚未尚未执行操作。Use this option when you will make a Bindings Library for the reference .jar but have not done so yet. 此生成操作可用于打包多个 .jars (和/或。AARs) 到多个相互依赖的绑定库。This build action is useful for packaging multiple .jars (and/or .AARs) into multiple interdependent Bindings Libraries.

  • EmbeddedReferenceJar – 将引用的嵌入 .jar到生成的绑定库。DLL。EmbeddedReferenceJar – Embeds a reference .jar into the resulting Bindings Library .DLL. 如果想要创建使用此生成操作C#的这两个输入绑定 .jar (或)。AAR) 和所有它的引用 .jar(s) 绑定库中。Use this build action when you want to create C# bindings for both the input .jar (or .AAR) and all of its reference .jar(s) in your Bindings Library.

  • EmbeddedNativeLibrary – 将嵌入到本机 .so到绑定。EmbeddedNativeLibrary – Embeds a native .so into the binding. 用于此生成操作 .so所需的文件 .jar文件被绑定。This build action is used for .so files that are required by the .jar file being bound. 它可能需要手动加载 .so库,然后从 Java 库执行代码。It may be necessary to manually load the .so library before executing code from the Java library. 这是如下所述。This is described below.

以下指南中的更详细地介绍了操作这些生成。These build actions are explained in more detail in the following guides.

此外,使用以下生成操作以帮助导入 Java API 文档和其转换为C#XML 文档:Additionally, the following build actions are used to help importing Java API documentation and convert them into C# XML documentation:

  • JavaDocJar 用于指向 Javadoc 存档 Jar 符合 Maven 包样式的 Java 库 (通常FOOBAR-javadoc**.jar**)。JavaDocJar is used to point to Javadoc archive Jar for a Java library that conforms to a Maven package style (usually FOOBAR-javadoc**.jar**).
  • JavaDocIndex 用于指向index.html中的 API 参考文档 HTML 文件。JavaDocIndex is used to point to index.html file within the API reference documentation HTML.
  • JavaSourceJar 用于补充JavaDocJar,以便首先从源生成 JavaDoc,然后将结果视为JavaDocIndex,符合 Maven 的 Java 库包样式 (通常FOOBAR-sources**.jar**)。JavaSourceJar is used to complement JavaDocJar, to first generate JavaDoc from sources and then treat the results as JavaDocIndex, for a Java library that conforms to a Maven package style (usually FOOBAR-sources**.jar**).

API 文档应为从 Java8、 Java7 或 Java6 SDK (它们是所有不同的格式),默认 doclet 或 DroidDoc 样式。The API documentation should be the default doclet from Java8, Java7 or Java6 SDK (they are all different format), or the DroidDoc style.

在绑定中包括本机库Including a Native Library in a Binding

可能有必要包括 .so库,请在 Xamarin.Android 绑定的绑定 Java 库的一部分。It may be necessary to include a .so library in a Xamarin.Android binding project as a part of binding a Java library. Xamarin.Android 已包装的 Java 代码执行时,将无法进行 JNI 调用和错误消息_java.lang.UnsatisfiedLinkError:找不到的本机方法:_ 会在 logcat 出应用程序中显示。When the wrapped Java code executes, Xamarin.Android will fail to make the JNI call and the error message java.lang.UnsatisfiedLinkError: Native method not found: will appear in the logcat out for the application.

此解决方法是手动加载 .so库通过调用Java.Lang.JavaSystem.LoadLibraryThe fix for this is to manually load the .so library with a call to Java.Lang.JavaSystem.LoadLibrary. 例如假设 Xamarin.Android 项目已共享库libpocketsphinx_jni.so绑定项目的生成操作中包含EmbeddedNativeLibrary,以下代码片段(使用共享的库之前执行) 将加载 .so库:For example assuming that a Xamarin.Android project has shared library libpocketsphinx_jni.so included in the binding project with a build action of EmbeddedNativeLibrary, the following snippet (executed before using the shared library) will load the .so library:

Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");

调整到 C 的 Java Api⧣Adapting Java APIs to C⧣

Xamarin.Android 绑定生成器会更改某些 Java 的惯用语言和模式,对应于.NET 的模式。The Xamarin.Android Binding Generator will change some Java idioms and patterns to correspond to .NET patterns. 以下列表介绍了如何将 Java 映射到C#/.NET:The following list describes how Java is mapped to C#/.NET:

  • _Setter/Getter 方法_在 Java 中都_属性_在.NET 中。Setter/Getter methods in Java are Properties in .NET.

  • _字段_在 Java 中都_属性_在.NET 中。Fields in Java are Properties in .NET.

  • _侦听器/侦听器接口_在 Java 中都_事件_在.NET 中。Listeners/Listener Interfaces in Java are Events in .NET. 回调接口中的方法的参数将由表示EventArgs子类。The parameters of methods in the callback interfaces will be represented by an EventArgs subclass.

  • 一个_静态嵌套类_在 Java 中是_嵌套类_在.NET 中。A Static Nested class in Java is a Nested class in .NET.

  • _内部类_在 Java 中是_嵌套类_实例构造函数中使用C#。An Inner class in Java is a Nested class with an instance constructor in C#.

绑定方案Binding Scenarios

以下绑定方案指南可帮助你为将合并到您的应用程序绑定 Java 库 (或库):The following binding scenario guides can help you bind a Java library (or libraries) for incorporation into your app:

  • 绑定。JAR是创建用于绑定库的演练 .jar文件。Binding a .JAR is a walkthrough for creating Bindings Libraries for .jar files.

  • 绑定。AAR是创建用于绑定库的演练。AAR 文件。Binding an .AAR is a walkthrough for creating Bindings Libraries for .AAR files. 阅读此演练,若要了解如何将绑定 Android Studio 库。Read this walkthrough to learn how to bind Android Studio libraries.

  • 绑定 Eclipse 库项目是从 Android 库项目中创建绑定库的演练。Binding an Eclipse Library Project is a walkthrough for creating binding libraries from Android Library Projects. 阅读此演练,若要了解如何将绑定 Eclipse Android 库项目。Read this walkthrough to learn how to bind Eclipse Android Library Projects.

  • 自定义绑定介绍了如何手动修改绑定以解决生成错误并调整所获得的 API,这样就更多"C#-例如"。Customizing Bindings explains how to make manual modifications to the binding to resolve build errors and shape the resulting API so that it is more "C#-like".

  • 绑定疑难解答列出了常见绑定错误方案,介绍了可能的原因,并提供了解决这些错误的建议。Troubleshooting Bindings lists common binding error scenarios, explains possible causes, and offers suggestions for resolving these errors.