Integrating Native Libraries in Android Projects
Modern Android applications often require native code for performance-critical operations or to leverage existing C/C++ libraries. This guide covers the process of biulding and bundling native shared libraries (.so files) into an Android project.
Setting Up Native Code
Create a native source file in your project's cpp directory. The following demonstrates a basic JNI function that returns a string:
#include <jni.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapp_MainActivity_getMessage(
JNIEnv *env,
jobject instance) {
return env->NewStringUTF("Native message received");
}
Configuring the Build System
Create a CMakeLists.txt file in your project root to define the build configuration:
cmake_minimum_required(VERSION 3.4.1)
add_library( my-native-lib SHARED src/main/cpp/my-native-lib.cpp )
find_library( log-lib log )
target_link_libraries( my-native-lib ${log-lib} )
In your build.gradle file, enable CMake integration:
android {
defaultConfig {
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
Building the Native Library
Execute a build to compile the native code. CMake processes the source files and produces the shared library. The compiled output appears in app/build/intermediates/cmake/debug/obj/ for debug builds.
Loading and Using the Library
Add a static initializer to load the native library and declare the native method:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("my-native-lib");
}
public native String getMessage();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String message = getMessage();
}
}
Bundlnig Libraries in the APK
The native libraries are automatically included in the APK under the lib/ directory during the standard build process. For explicit control over library placement, configure the source sets in build.gradle:
android {
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
}
This ensures the libraries end up in the correct ABI subdirectories (armeabi-v7a, arm64-v8a, x86, x86_64) within the APK's lib folder.