You might have created a .NET binding library by yourself by following the guide Binding a Java library from Microsoft docs. In many cases, it’s quite simple and straight forward for small libraries. However, there few drawbacks:
1/ You normally embed the native libraries artifacts inside your DLL
1.a/ This makes your DLL is potentially very large
1.b/ It might causes conflicts if two different Nuget packages embed the same libraries
1.c/ We cannot utilize if the native libraries are already downloaded by Android Studio or other Android development tools.
2/ You might try out Xamarin.Build.Download to download the libraries for you
The good point: We can get rid of item 1.a
Items 1.b & 1.c still persist
Other than that, a library normally doesn’t come without dependencies, we will have to analyze ourselves to find out
if there is a NuGet available out there
if not, we will need to create the binding ourselves
The things even get more headache when the libraries are privately distributed and protected with credentials on Gradle repositories.
By creating a lot of binding libraries (many are very big ones like Mapbox, Stripe, etc), I found the way that we can
Utilize Gradle - the native tool to manage Android/Java libraries either without credentials or with credentials, to download the libraries for us and a.
Find out the dependencies easily by reading POM files
Find out which dependencies are already bound with public NuGet packages
Upgrade version easily
In this series of Creating binding libraries for .NET Android, I will go through things step by step of how to use my approach for your own binding libraries based on my repository tuyen-vuduc/dotnet-binding-utils. At the end, you will get NuGet package(s) to use in your .NET Android app.
What do we have in this repository
1/ It is a toolset to create an .NET Android(Java) binding library
It will analyze all dependencies of the targeting binding library by reading POM files downloaded by Gradle
It will generate .NET Android (Java) binding library project(s) with appropriate dependencies
It will build and pack the final result in NuGet packages
2/ It manages metadata of many .NET Android(Java) binding libraries
- Any Android (Java) binding libraries available on Nuget.org can have its metadata defined in this repo
Based on available metadata, it will link the corresponding NuGet packages of the dependencies to the generated CSPROJ file
If a NuGet is available without its metadata,
1/ We need to add a new one similar to existing ones
2/ Then run the tool again
If not available, then a binding library project will be generated
3/ It has several scripts to simplify binding error fixes
// process_field(); // generate metadata to change fields’ managed names to avoid name conflicts.
// process_IJsonDeserializer(); // genereate xpath for classes inherits from IJsonDeserializer
// process_Com_Example_Dsroom_Dao_IBaseDao();
// process_Com_Google_Android_Material_Circularreveal_ICircularRevealWidget();
// process_Android_Util_ITypeEvaluator();
// process_Android_Util_Property();
// process_downgrade();
Here are typical steps to create a new binding library
1/ Fork my repository
2/ Open Git Bash on Windows or Terminal on other systems
3/ Ensure the existing metadata up to date by running sh fetch.sh
4/ Find the library Gradle details
The Gradle implementation of the library e.g.
de.hdodenhof:circleimageview:3.1.0
The Gradle repository details
URL
Credentials
By default, only these public repositories are supported
Maven Central
Google
JCenter
5/ Create the binding libraries by running sh bind.sh —artifact {YOUR_BINDIDNG_LIBRARY_IMPLEMETNATION_SYNTAX_IN_GRADLE}
6/ Fix all binding errors as reported then do the step 5 again until no more errors reported
7/ Create a PR to merge your changes to the main repository
If you’re lucky, you won’t have to do step 6 where no errors reported, there will be NuGet packages generated in nugets
folder. Otherwise, you need to be patient and careful to fix all reported errors then do step 7 as the final step.
With generated NuGet packages, you can consume them locally or distribute wherever you prefer.
Let’s create a binding library
In this simple demonstration, let’s create the binding library for de.hdodenhof:circleimageview:3.1.0
as mentioned the guide from Microsoft referred early in this post.
1/ Fork the library
Please do the fork then clone to your local machine if you haven’t.
2/ Open bash based terminal
Open the repository in Visual Studio Code
Open bash based terminal panel as well
- On Windows, I normally use Git Bash which is installed along with Git for Windows.
3/ Ensure the metadata up-to-date
I created a simple XUnit test to fetch the metadata of the existing libraries defined in the repository easily.
To invoke the update process, simply run sh fetch.sh
on your preferred bash based terminal.
On Windows, I recommend use Git Bash which comes along when you install Git for Windows.
As you can see, after running the script, there are many libraries updated either a new patch or even a new version.
Commit these changes before moving onward.
4/ Find the library’s Gradle details
After searching circleimageview
on Google Search, we can see its GitHub repository
By checking out the README, we can easily find out the Gradle implementation of the library.
dependencies {
...
implementation 'de.hdodenhof:circleimageview:3.1.0'
}
What we need is the value of de.hdodenhof:circleimageview:3.1.0
NOTE: Android/Libraries are normally distributed on Maven Central repository which is similar to NuGet.org in .NET world. You can search for the libraries there as well to easily get their latest versions if not presented in the README.
5/ Create the binding library
Creating a binding library normally requires many steps, but I created a script, bind.sh
, to make our life easier. Executing it will
Create the binding library project for the targeted library
Add NuGet packages for all dependencies having corresponding metadata
Add and link binding projects for dependencies without corresponding metadata
The syntax is
# sh bind.sh —artifact {ARTIFACT_GROUP}:{ARTIFACT_NAME}:{VERSION}
sh bind.sh —artifact de.hdodenhof:circleimageview:3.1.0
Here is what you can see when executing sh bind.sh —artifact de.hdodenhof:circleimageview:3.1.0
- It’s starting
- It’s successfully without any binding errors
As you can see on the right left hand side, a binding project is created with all required files which are for fixing binding errors.
6/ Fix reported binding errors
As you can see, no errors are reported, then we can skip this step.
The process of fixing binding errors sometimes is very simple, but sometimes is very complex; however, we need to always follow the guide from Microsoft as the base line.
7/ Create the PR to merge your new binding library to my repository
Commit all the changes then create the PR.
Please follow the guide from GitHub to complete this step.
We can skip if for now and check out the generated library packed as a NuGet library first.
You can use it locally or upload it to NuGet.org then use. If you prefer a local try first, you can check out this guide if you don’t know yet.
Wraps up
In this post, I introduced you my repository dotnet-binding-utils which is to utilize Gradle and other custom scripts to simplify the process of creating an Android binding library. The major benefits are
Utilize the native Android package management to manage Android dependencies
Reduce diskspace if we work on both Android native development and .NET Android development
Simple process
Results consumed easily as NuGet packages
I hope it will help and benefit you guys.
It’s just the start, there are many other scenarios, please check out my other related posts (upcoming).
Happy coding!!!
NOTE: Microsoft also introduced a new way of adding a native Android library which is publicly available on Maven Central library. What I don’t like is it doesn’t utilize Gradle but
Xamarin.Build.Download
to download the dependency.