Creating Xamarin.Android Binding Library

To reference a Jar or Aar file in your Xamarin project, you can create a binding project to access the file. This is sometimes needed if you have code written in Java or an SDK that you need to access from Xamarin.

I will be doing a sample of how to bind the Google Play Services Wallet SDK. Please note that Xamarin have already done this for you, and you can just download from Nuget most of the Google Play Services Binding Libraries. This is just an example.

Create Project

First, create an Android Binding Library Project.

Add Java File

Next you add your Java file. If it is an ‘aar’ file, then set the build action to LibraryProjectZip. If it is a ‘jar’ file, set the build action to InputJar.

Check References

Most SDK’s will also reference other Java files. So you need to look for a *.pom file with your java file. In here, it will contain what references are required. For example, the Wallet service shows.

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.google.android.gms</groupId>
  <artifactId>play-services-wallet</artifactId>
  <version>11.0.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>com.google.android.gms</groupId>
      <artifactId>play-services-base</artifactId>
      <version>11.0.0</version>
      <scope>compile</scope>
      <type>aar</type>
    </dependency>
    <dependency>
      <groupId>com.google.android.gms</groupId>
      <artifactId>play-services-basement</artifactId>
      <version>11.0.0</version>
      <scope>compile</scope>
      <type>aar</type>
    </dependency>
    <dependency>
      <groupId>com.google.android.gms</groupId>
      <artifactId>play-services-identity</artifactId>
      <version>11.0.0</version>
      <scope>compile</scope>
      <type>aar</type>
    </dependency>
    <dependency>
      <groupId>com.google.android.gms</groupId>
      <artifactId>play-services-maps</artifactId>
      <version>11.0.0</version>
      <scope>compile</scope>
      <type>aar</type>
    </dependency>
  </dependencies>
</project>

As you can see here, it contains 4 references. We now have to get the aar file for each of these references. Add them to your project, and set the build action to EmbeddedReferenceJar.

Please note, that you will also have to look at the *.pom file for each reference, and also add any of those references, and so forth. You don’t have to add any of the Android Support Libraries however, as they are added during the build.

Build Output

Now we get to build. There may be errors that appear, which we will cover shortly, or it may build successfully. But, a successful build, doesn’t mean it worked successfully either. To ensure it did work, you have to go to the Build Output window and see what is happening.

If you forgot to add certain references, you are very likely to get a build output, looking like this.

This type of error message is basically saying that something isn’t referenced, but it doesn’t give you much of hint as to what it is.

1>JARTOXML : warning J2X9001: Couldn't load class com/google/android/gms/internal/hf : java.lang.NoClassDefFoundError: com/google/android/gms/internal/zzed

 

Double check all references are added, and they have their Build Action set to EmbeddedReferenceJar.

Special Note: I also discovered you can get this error if the Class Parser isn’t set to class-parse. You can set this in the properties of the Binding project, or you can add this to your csproj, just under the line <AndroidCodegenTarget>XamarinAndroid</AndroidCodegenTarget>.

<AndroidClassParser>class-parse</AndroidClassParser>

I had a strange issue, where I set it in properties, but it didn’t save it to the csproj. So take the extra step and look inside the csproj to make sure the line is there.

Check API

While there may be some warnings or errors, you can check out the api.xml file that is located in obj > Debug > api.xml.

This file contains the APIs it is trying to make public, and it can be used to debug any errors that are preventing you from building.

Transformations

Looking at the API, gives you great context, to be able to make transformations. Sometimes a field name might be the same as the class or interface it is contained in. While legal for Java, it is illegal for C#. With this you can go to the Transformations folder and open the Metadata.xml file. It has some examples of removing nodes. You can also add and rename nodes if desired.

<remove-node path="/api/package[@name='com.google.android.gms.wallet']/interface[@name='Wallet']/field[@name='Wallet']" />

It’s easy to modify. There are different nodes you can choose, classes, interfaces, fields, methods etc. Just do /node[@name=’TheName’]/ etc. Just follow the structure of the xml file to reach the node, you will see they match 1 to 1.

Using Binding

Once you have a successfully building binding project, you can reference it just like any other project, to your Xamarin.Android project. You will notice that lowercase names have been switched to PascalCasing.

Com.Google.Android.Gms.Wallet

If you want to make sure the binding was successful. When you reference a project, you can double click the reference to open up the Object Browser, and view the classes and methods available.

More Information

If you want a more detailed look at some parts of the binding process, Jon Douglas has a guide Approaching a Xamarin.Android Bindings Case that contains more information, right from the developer who helped build the binding engine.


XAMARIN WEEKLY NEWSLETTER

Subscribe to a hand-picked round up of the best Xamarin development links every week. Published every Friday. Free.

Signup to Weekly Xamarin

* I do not maintain or run this newsletter, but I do recommend it.

Microsoft MVP | Xamarin MVP | Xamarin Forms Developer | Build Flutter

6 Comments

  1. Ahmad ElMadi

    Great article, I personally think that this field is one of the most powerful features in Xamarin (or crossplatform development) and yet it is kind of very ignored and abandoned by Xamarin.
    poor documentation, not much of helping tools. I think this one needs more investment way more than things like Xamarin Forms Embedding or Embeddinator-4000 .

    I am saying this because it gets easily frustrating for the developer especially when we see hundreds of errors and warnings and have no clue where to start and what transformations we need to solve them and what can be just ignored .

    I think when it comes to documentation we there should be a table of common errors and warnings and how people can deal with them.

    The documentation should also have a description of how to get the AAR file or generate one . What about if one library depends on another library .

    A great example of a challenging library to bind is the Facebook SDK . binding it comes with a bunch of challenges that can be a guide for others .

    Of course on top of all, a good tool that fixes the obvious issues and add the ability to document the methods and parameters would be the best solution for everyone .

    What do you think ?

    1. Adam Pedley

      Well I certainly found the documentation lacking, and the errors I ran into, I didn’t really find anyway, I had to figure out that myself. Luckily I know Xamarin eco system rather well, so I could find my way through.

      However I have know another company to attempt and completely give up on binding the Facebook SDK, due to its complexity. Projects I do, I rarely come across binding requirements, but given my recent first attempt of start to finish, it wasn’t a simple experience.

  2. Paramjit Singh

    Articles on xamrinhelp are very useful. I am curious how to do this on Mac or iOS. Is it possible to bind native frameworks on Apple ecosystem with xamarin. Does this type of binding work with native projects or it can used from Shared code.