ANDROID JNI EXAMPLE . If you want to know about ANDROID JNI EXAMPLE , then this article is for you.

ANDROID JNI EXAMPLE


Android JNI Example: Calling Native C++ Code from Java

In this article, we'll walk through a basic example of integrating JNI (Java Native Interface) into an Android project. The goal is to demonstrate how you can call native C++ code from your Android Java code and how to set up the JNI environment.

Why Use JNI?

JNI allows Java code running on Android to interact with native code written in languages like C and C++. This is especially useful for tasks that require high performance, memory management, or when you need to use pre-existing C/C++ libraries.


Setting Up a Simple Android Project with JNI

Let’s go through the steps to integrate C++ code with an Android project using JNI.

Step 1: Create a New Android Project

  1. Open Android Studio and create a new project.
  2. Select Empty Activity.
  3. Choose Java as the programming language (or Kotlin if you prefer).
  4. Name the project and select the appropriate SDK version.

Step 2: Add C++ Support to the Project

When you create a new project, Android Studio gives you an option to add C++ support. If you didn't select C++ during the project creation, you can still add it manually later. Here's how to add C++ support to your project:

  1. Right-click on the app directory in the Project view and select New > New Module.
  2. Choose C++ as the language option. This will automatically configure the necessary files and directories for native development.

This creates a cpp folder inside your src/main directory, where you can add C++ files for JNI integration.


Step 3: Write C++ Code

Create a new C++ source file. To do this:

  1. Navigate to app/src/main/cpp/ directory in your project.
  2. Right-click and select New > C++ Source File.
  3. Name the file native-lib.cpp.

Inside native-lib.cpp, you’ll define the C++ function that you want to call from Java. Here’s a simple C++ function that returns a string:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(JNIEnv* env, jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
  • JNIEXPORT: This is a macro to specify that the function should be available for JNI calls.
  • Java_com_example_myapplication_MainActivity_stringFromJNI: The function name follows a specific naming convention: Java_ + <package> + <class> + <method>. This name allows the Java code to locate the native function.
  • JNIEnv: Provides access to JNI functions. It's used to interact with Java objects and manage data between Java and native code.
  • env->NewStringUTF: This creates a new jstring from the C++ string, which can be returned to Java.

Step 4: Declare the Native Method in Java

In your MainActivity.java (or MainActivity.kt if using Kotlin), declare the native method that you will call from C++:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    // Declare the native method
    public native String stringFromJNI();

    // Load the native library
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Call the native method
        String result = stringFromJNI();
        System.out.println(result);  // Output: "Hello from C++"
    }
}
  • The native keyword in Java is used to declare a method that will be implemented in native code (C/C++).
  • System.loadLibrary("native-lib") loads the compiled C++ shared library (native-lib.so) into your application at runtime.

Step 5: Configure CMakeLists.txt

Android uses CMake to build native code. You need to configure the CMakeLists.txt file to tell Android how to compile your C++ code.

Open the app/CMakeLists.txt file and add the following content:

cmake_minimum_required(VERSION 3.4.1)

# Add your native source files here
add_library(native-lib SHARED
            src/main/cpp/native-lib.cpp)

# Find required libraries
find_library(log-lib log)

# Link native libraries
target_link_libraries(native-lib
                      ${log-lib})
  • add_library(native-lib SHARED src/main/cpp/native-lib.cpp): This command tells CMake to compile the native-lib.cpp file into a shared library (native-lib.so).
  • find_library(log-lib log): This line links the log library (Android’s logging system) to your C++ code.
  • target_link_libraries(native-lib ${log-lib}): This command links the shared library with the log library to ensure proper functionality.

Step 6: Build and Run Your Project

  1. Build your project by clicking on Build > Make Project in Android Studio.
  2. Run your app on an Android emulator or physical device.
  3. When the app runs, the stringFromJNI() method will call the C++ function, and it will return the string "Hello from C++", which will be displayed in the Logcat.

Step-by-Step Example Breakdown

Here is the complete summary of files and steps involved:

1. C++ Code (native-lib.cpp)

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(JNIEnv* env, jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

2. Java Code (MainActivity.java)

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    // Declare the native method
    public native String stringFromJNI();

    // Load the native library
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Call the native method
        String result = stringFromJNI();
        System.out.println(result);  // Output: "Hello from C++"
    }
}

3. CMakeLists.txt Configuration

cmake_minimum_required(VERSION 3.4.1)

add_library(native-lib SHARED
            src/main/cpp/native-lib.cpp)

find_library(log-lib log)

target_link_libraries(native-lib
                      ${log-lib})

JNI Data Types

When working with JNI, you need to understand the JNI data types that bridge Java and C/C++ code:

  • jint: Represents int in Java.
  • jboolean: Represents boolean in Java.
  • jobject: Represents any Java object.
  • jstring: Represents Java String.
  • jarray: Represents Java arrays.

These types allow you to pass data between Java and native code seamlessly.


Conclusion

JNI is a powerful way to call native C/C++ code from your Android Java code. It is particularly useful for performance-critical tasks, accessing system-level functionalities, or reusing existing libraries written in other languages. By following the steps outlined in this article, you’ve learned how to set up JNI in an Android project, how to call native C++ methods from Java, and how to configure the necessary files to make everything work.

While JNI is useful, it should be used sparingly due to its complexity and potential for bugs. Always ensure that native code is carefully managed to avoid memory leaks and crashes.