Build an Android bridge in Unity games

David Silvera
Voodoo Engineering
Published in
5 min readOct 28, 2020

At Voodoo, all our games are programmed in the Unity language. Some features are straightforward, faster, and more robust to develop in native languages. For instance, we can have a team that works in native ads SDK and we (Unity) want to communicate with this latter (SDK). For that, we need to make a bridge between native languages and Unity.

This article explains how to do that in Android language (for iOS, you can refer to this article: https://medium.com/voodoo-engineering/bringing-native-ios-frameworks-into-unity-games-by-hacking-ios-methods-2c656d18cf9b).

In order, to understand the method we will use, let’s take this example: we want to ask an Android SDK to execute an addition between two numbers and send back the result.

Android side

First of all, create an Android project with Android Studio and start a module. You are now ready to work on this new module.

To develop it, you need unity-classes.jar file which contains all the necessary unity classes to make an Android bridge. To retrieve the above-mentioned file, you can export an Android project in Unity editor and get it in the generated project. Copy paste it in the same directory of your Gradle file from your Android module. Make sure not to paste it in the lib repository because you do not want to include it when producing your bridge library, Unity already includes it.

In your Gradle dependencies, you must add :

compileOnly files('unity-classes.jar')

Through the line above, you can use all the dependency classes but it will never get attached to your AAR file.

You need two classes:

  • the first one to send a request to Android: you will call it MathManager
  • the second one to send back the result: MathCallback

Send a result to Unity

You will develop this code first to make the next one more easily. Let’s create MathCallback interface in Java (it also can work in Kotlin but for a better understanding you will develop it in Java). This interface will incorporate all methods to be implemented in the Unity side.

Here, you can see that you set a method signature to return the result of the addition.

That’s all for this part as for the Android side.

Send a request to Android

Create a class MathManager in Java within the Android module previously created. In this class, all your methods will be static. Thus, Unity can call them directly.

The first method will set the callback class instance in order to then be able to send Unity the result.

public static void SetCallback(MathCallback callback) {  Log.d("MathManager", "SetCallback");  this.callback = callback;}

What with the above code, you store the callback into a static private variable called “callback”.

After that, you can create the main method to make the calculation:

public static void Add(int var1, int var2){   callback.AddResult(var1 + var2);}

You only add var1 to var2 and send the result with the callback instance.

Generate the bridge library

To generate the AAR file easily, I recommend that you add some tasks in your Gradle file like that:

The first task will copy the AAR file into a folder named “release”

The second will create a group named “Math” to execute the task more quickly. This task will build the project and execute the first task so the AAR is copied.

You can easily execute this task if you open the Gradle overlay in Android Studio and double click in your task :

You can copy the generated file into your unity project to be able to use it.

Unity side

To develop this part, do not forget to copy your android bridge library.

In this part, you will see how to create the callback and how you will call an Android static method.

Get Android result

First, you will see how to create a proxy to instantiate an Android interface.

Here the code:

You use AndroidJavaProxy to bind your MathCallback Android interface and MathCallback Unity class. In the constructor, you use the method called “base” to give the full Android class name with the package. Here, my interface is declared in the io.voodoo.math package into my Android library.

And finally, you can develop the method used on the interface and get the result. You can see that the method has the same signature as the Android interface.

To get the result of a bridge callback, you can use other techniques like using the method called UnityPlayer.UnitySendMessage

But personally, I prefer the proxy technique which is easy to implement and more structured.

Call Android method

To start this part, you need to send an instance of your interface. Here is the code :

new AndroidJavaClass("io.voodoo.math.MathManager").CallStatic("SetCallback", new MathCallback());

You created an instance of your Android class MathManager and call the static method SetCallback. Has a parameter of it, you give an instance of your unity proxy (which implements your Android interface). Like that, you set the callback first. You can now call the second method and get the result:

new AndroidJavaClass("io.voodoo.math.MathManager").CallStatic("Add", 1, 2);

Like you did previously, you instantiated a java class and called the static method “Add” with 2 parameters: 1 and 2. The result of this method will be appearing into your proxy along with the result of 3.

Note, you can store the AndroidJavaClass not to create it each time.

Communicate with the current Activity

Sometimes, you need to communicate with the current activity or get an application context.

To do so, you can add a static method into your MathManager class like that:

private static MathActivity getActivity() {   Activity currentActivity = UnityPlayer.currentActivity;   if (currentActivity instanceof MathActivity)      return (MathActivity) currentActivity;   return null;}

MathActivity is the name of your current activity.

This method uses the unity jar library. UnityPlayer.currentActivity returns the current activity. In the Unity project, I recommend that you develop in a single activity to feel more comfortable.

Conclusion

Sometimes it is more interesting to develop some features in native languages. I hope this article helps you to understand that it is not complicated to do that in Android. With this method, you can now develop a lot of complex features and use all native methods for your games.

--

--