Unity: C# to Android and Android to C#

m0skit0
3 min readApr 20, 2020

--

That cube is awesome, isn’t it?

So recently I was introduced to the wonderful world of Unity and its C#-based development (I will reserve my opinion about C# as a language for another day). Being mostly an Android developer, I will mainly focus on Unity over Android here. Without further delay, let’s start.

C# to Android

Calling Java (or Kotlin) functions from C# is pretty well documented. You mainly have 3 APIs on the Unity Engine SDK: AndroidJavaClass, AndroidJavaObject, and AndroidJavaProxy. They are pretty well documented, but I will give a quick introduction here:

  • AndroidJavaClass: represents a Java class. You can instantiate this object by passing it the name of a Java class and after that you can access everything you could access in that Java class (e.g. static methods, static fields, etc…).
  • AndroidJavaObject: represents a Java object instance. You can instantiate this object by passing it the name of a Java class and the parameters to its constructor (remember that the parameters must be primitives or AndroidJavaObjects or AndroidJavaProxy) if there are any. Then you can call any methods on that instance as if it were a Java class instance, passing required parameters as well (again the same limitations than constructor parameters apply).
  • AndroidJavaProxy: represents an implementation of a Java interface. This is extremely useful for passing listeners to Java and receiving the callback directly in C#.

To better leverage this API I prefer to wrap every AndroidJavaObject inside a C# class which exposes a nice API for C# but internally redirects the calls to Java. Here’s what my JavaObjectWrapper class looks like (please keep in mind this was my first C# coding ever, don’t be too harsh!).

Then let’s suppose I have a Player Java class that I want to interact with from Unity. I would wrap it like this:

This way we can provide a nice API to interact with from C# and reduce the number of errors due to typos in method names, parameters and such.

Android to C#

Usually you don’t need any kind of interaction from Android to Unity, and if you need to use a callback API you can resort to AndroidJavaProxy. However there are some special cases where there is no callback API although the Android part behaves like a callback, for example when you start an Activity and wait for it to return some value (i.e. startActivityForResult) or you want to do some background work on the Android level because it improves performance, or receive a broadcasted intent. You surely get the idea.

In these cases all the answers I could find on the web suggested to use the dreadful UnitySendMessage API. This is a horrible solution in many ways:

  • You can only send messages to game objects by their name.
  • Method of that game object is called as a string (similar to the JNI API from C#).
  • There’s only one single string argument.

These are very limiting and will make your code look very ugly if you ever want to pass a something more complicated than a primitive from Android to C# as the parameter and to keep your code structured without having to resort to God-like game objects and anti-patterns that violate every SOLID principle.

There’s a much more friendly solution however, and we already commented it: AndroidJavaProxy. Instead of using UnitySendMessage you can simply define your interfaces in Java to listen to from C# and make your C# class implement the Java interface and pass it to the Android layer. For example, I can define the following interface in Java (or Kotlin):

Then implement it in C#:

The write your own API that accepts this listener as parameter to launch your activity (or whatever you want to do in Android that requires a listener that is not provided by standard Android API) and pass an instance of the GenericJavaInterfaceImpl that will be called from Java whenever you like. So for example if you use startActivityForResult() you can simply wait for the activity to finish and calls onActivityResult(), then call your listener from there with the result.

I personally find this method much more flexible and cleaner than UnitySendMessage and allows me to write more readable, less bug-ridden, and more maintainable code.

Well, I hope you found this article interesting. If you have any comments or questions please do not hesitate to let me know in the comments below!

And that’s all, folks!

--

--