Binding a Java Library - Xamarin (original) (raw)


Share via


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

The third-party library ecosystem for Android is massive. Because of this, it frequently makes sense to use an existing Android library than to create a new one. Xamarin.Android offers two ways to use these libraries:

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. For more information about using JNI, see Working with JNI.

Xamarin.Android implements bindings by using Managed Callable Wrappers (MCW). MCW is a JNI bridge that is used when managed code needs to invoke Java code. Managed callable wrappers also provide support for subclassing Java types and for overriding virtual methods on Java types. 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 bridge architecture

A Bindings Library is an assembly containing Managed Callable Wrappers for Java types. 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) { ... }
}

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);

To create this Bindings Library, you use the Xamarin.Android Java Bindings Library template. The resulting binding project creates a .NET assembly with the MCW classes, .jar file(s), and resources for Android Library projects embedded in it. You can also create Bindings Libraries for Android Archive (.AAR) files and Eclipse Android Library projects. 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. 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. For example, if the Java package name for your bound .jar is the following:

com.company.package

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;

When binding an existing Android library, it is necessary to keep the following points in mind:

Build Actions

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:

These build actions are explained in more detail in the following guides.

Additionally, the following build actions are used to help importing Java API documentation and convert them into C# XML documentation:

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

It may be necessary to include a .so library in a Xamarin.Android binding project as a part of binding a Java library. 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.

The fix for this is to manually load the .so library with a call to Java.Lang.JavaSystem.LoadLibrary. 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");

Adapting Java APIs to C⧣

The Xamarin.Android Binding Generator will change some Java idioms and patterns to correspond to .NET patterns. The following list describes how Java is mapped to C#/.NET:

Binding Scenarios

The following binding scenario guides can help you bind a Java library (or libraries) for incorporation into your app: