Android NDK: Calling Kotlin from Native Code

Ihor Kucherenko

Android developer

SHARE

2

In our previous article, Android NDK: The Interaction Between Kotlin and C/C++, we shared the results of our research into the Android NDK (Native Development Kit). In that article, you can find out how to set C/C++ and Kotlin interaction. We showed how Kotlin can invoke C/C++ code with any data types. We also converted String instances and passed Kotlin objects to native code, called functions, and threw JDK (Java Development Kit) exceptions.

Now it’s time to move to the practical part working with the Android NDK. In this article, we’ll dive deeper into the topic of working with Kotlin in the Android NDK and will tell you how to call Kotlin from native code.

Why do you need to call Kotlin from native code?

The most obvious reason to call Kotlin from native code is for callbacks. When you perform an operation, you need to know when it’s done and receive the result of that operation. This is true whether you work with Kotlin or the JNI (Java Native Interface). In this article, we’ll give examples of how to find out when a new value is persisted to memory. We showed how a new value is created in one of our previous articles.

Calling static properties

The JNIEnv pointer contains many functions to deal with static fields. First, you have to get the ID of the static field using the jfieldID GetStaticFieldID(JNIEnv *env, jclassclazz, const char *name, const char *sig) function.

Kotlin doesn’t have static members, but each Kotlin class can have a companion object, so you can use companion objects’ fields and functions similarly. A companion object is initialized when the corresponding class is loaded, matching the semantics of the Java static initializer. Thus, you can use a companion object to load native libraries:

To determine a method’s signature, use type codes. The following table summarizes the various types available in the JNI, along with their codes:

In the picture above, the compiler generates a private static field in the Store class. The Store class contains fields with the private modifier. You can’t access those fields from the Store class. But with the JNI, you can access the values of those fields even if the private modifier is set.

If you just create this field in a simple class, you get an exception: java.lang.NoSuchFieldError: no “I” field “static” in class “Lcom/ihorkucherenko/storage/Store;” or its superclasses. If you use the Int? type, you also receive this error. To avoid this error, follow the instructions below.

Calling static methods

To get the ID of a static method, you have to usejmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig).

JNIEnv contains three types of functions that can call static methods:

Calling an instance’s properties

Similarly to the previous code examples, you should use functions to retrieve the ID of the field and value: jfieldID GetFieldID(JNIEnv *env, jclassclazz, const char *name, const char *sig).

Let’s add private val property = 3, which is equal to private final I property = 3 in bytecode, to the Store class. After that, you have to get jobject, which refers to the instance of the Store class, in order to retrieve the value from property. For example, you can create a new jobject inside the native code and get the value:

In this article, we told you how we extended the in-memory store example. You found out how to receive a value from a Kotlin instance and Kotlin static fields in native code, how to use calling Kotlin methods using the CallStatic<Type>Method and Call<Type>Method functions, and how to create a new jobject in C/C++. Now you can easily work with Android NDK and the JNI using Kotlin instead of Java for Android development.

4.4/ 5.0

Article rating

50

Reviews

Remember those Facebook reactions? Well, we aren't Facebook but we love reactions too. They can give us valuable insights on how to improve what we're doing. Would you tell us how you feel about this article?