Jar, Jni and .so files

Great question! This touches on the core of Android's native interface.

Let’s break this down step-by-step from the very basics to how .so files, jniLibs, and JNI work in an Android project — especially in the context of using a .jar file that relies on native code.


🔹 What is JNI?

JNI stands for Java Native Interface.

It is a bridge that allows Java/Kotlin code to call functions written in native code — typically C or C++.

This is useful when:

  • You need high performance (e.g., image processing, cryptography).

  • You want to reuse existing C/C++ libraries in your Android app.

  • You're interfacing with hardware or OS-level features.


🔹 What is a .so file?

  • .so = Shared Object file (Linux equivalent of .dll in Windows).

  • It is a compiled binary that contains native (C/C++) functions.

  • Android apps use .so files for native libraries.

For example:

libmynative.so

is a native library your app might need to run some C/C++ code from Java/Kotlin using JNI.


🔹 What is jniLibs/?

jniLibs/ is a special directory in Android projects where you put your native libraries (.so files).

Structure:

Each subfolder corresponds to a CPU architecture (ABI). Android supports multiple ABIs, including:

  • armeabi-v7a → 32-bit ARM

  • arm64-v8a → 64-bit ARM

  • x86 → Intel (emulators)

  • x86_64 → 64-bit Intel

So you need to provide .so files for each ABI your app supports.


🔄 How JAR + .so Works with JNI

Let’s say:

  • You import a JAR file: libnativeclient.jar

  • Inside the JAR, it contains Java code like this:

This means:

  • System.loadLibrary("nativeclient") tells the JVM to load libnativeclient.so

  • getSerialNumber() is a native function implemented in C/C++

You must ensure:

  • The .so file libnativeclient.so is present in your project’s jniLibs/<abi>/ directory.

  • The method is implemented in your .cpp file (e.g., nativeclient.cpp).


🔥 What Happens at Runtime

At app launch:

  1. The app loads the class.

  2. System.loadLibrary("nativeclient") executes → looks for libnativeclient.so in:

    • /data/app/<your.package>/lib/<abi>/

    • Which comes from the jniLibs directory during the build.

  3. The native function getSerialNumber() is now callable.

If the .so file is missing: You’ll get this error:


🔧 How to Add .so Files to Your Project

Step 1: Place .so files in the right folder

Step 2: Update build.gradle

Gradle picks up native libraries automatically from jniLibs, but make sure you don't strip them:

Optional (but recommended) in build.gradle:


✅ Summary Table

Concept
Description

JNI

A bridge to call C/C++ code from Java/Kotlin

.so file

Shared library file with compiled native code

jniLibs/

Folder to place .so files for Android builds

System.loadLibrary("x")

Loads libx.so from native libs at runtime

Error if missing

UnsatisfiedLinkError: dlopen failed


Would you like a small working example of Java + native C/C++ JNI code in Android? Or how to link it with Gradle and verify loading works?

Last updated