A Guide to Building Android Libraries with NDK from Scratch
- published
- reading time
- 3 minutes
Introduction
Building Android libraries with the NDK (Native Development Kit) can greatly enhance the performance and capabilities of your Android apps, especially when dealing with computationally intensive tasks or utilizing native code. Here’s a step-by-step guide to get you started:
Prerequisites
Before diving into building Android libraries with NDK, ensure you have the following:
- Android Studio installed
- Android NDK installed and configured in your project
Step 1: Set Up Your Android Project
- Open Android Studio and create a new Android project or open an existing one.
- Make sure you have the necessary SDKs and build tools installed for your project.
Step 2: Create Your JNI Folder Structure
Inside your Android project, create a new folder to hold your JNI code. Conventionally, this folder is named jni or src/main/jni.
Alternatively, you have the option to manually navigate to your project directory and create the jni directory yourself.
In my situation, my Android Studio projects are located at /home/kali/AndroidStudioProjects/, and specifically, this JNI_App project is at /home/kali/AndroidStudioProjects/JNI_App/.
$ cd /home/kali/AndroidStudioProjects/JNI_App/
$ cd app/src/main/
$ mkdir jni
$ ls
AndroidManifest.xml java jni res
Within the jni folder, create a C source file (e.g., native-lib.c). This file will contain the native C code you want to call from your Java/Kotlin code.
To do this follow the following steps:
- Next, in the jni directory, right-click and choose New -> CMakeLists.txt. Also, select New -> C/C++ Source File -> {Name -> native-lib & Type -> C}.
Step 3: Write a native method in Java
In your Java class (usually referred to as a “bridge” class), define the native method. This will act as a bridge between your Java code and the native C/C++ code.
Right Click on com.example.jni_app -> New -> Java Class -> HelloJNI Class
It will look like :
package com.example.jni_app;
public class HelloJNI {
}
Add the following content to it:
package com.example.jni_app;
public class HelloJNI {
static {
System.loadLibrary("native-lib");
}
public native String printStr();
}
We will use the library libnative-lib.so. This is naming convention that lib and .so should be dropped from library name and include it in System.loadLibrary()
Step 3: Generate the header file
Run the following command in your project’s directory to generate the header file for your native methods.
We have HelloJNI.java located at /app/src/main/java/com/example/jni_app
$ javac -h . HelloJNI.java
$ ls
com_example_jni_app_HelloJNI.h HelloJNI.java
HelloJNI.class MainActivity.java
This command will generate a com_example_jni_app_HelloJNI.h file.
Step 4: Write the native implementation
Open native-lib.c inside the jni directory and implement the native method.
#include <jni.h>
#include "com_example_jni_app_HelloJNI.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_jni_app_HelloJNI_printStr(JNIEnv* env, jobject jobj) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
Step 5: Create the Android.mk file
Create an Android.mk file inside the jni directory to define the build rules for the native code.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := native-lib.c
include $(BUILD_SHARED_LIBRARY)
Step 6: Build the native library
Open a terminal and navigate to your project’s root directory. Run the following command to build the native library.
$ ndk-build