[Android-NDK] Creating shared library and using them in Android Oreo 8 and 8.1

[Android-NDK] Creating shared library and using them in Android Oreo 8 and 8.1

In this post I’m going to show how to build shared library for android and using them. I’m using Ubuntu 16.04 LTS running inside a VM and Android Studio 3.2.1 running on windows 10.

Step1: Setting up the environment

  • Get Android NDK (https://developer.android.com/ndk/downloads). At the time of writing this post I’m using android-ndk-r19c-linux-x86_64.zip
  • Unizp the downloaded file and change directory into android-ndk-r19c. In this directory you should see a binary called “ndk-build”. We will use this binary to build the shared library.

  • We will add path for this directory in the PATH variable. We can use the export command to set the PATH variable. Assuming you have downloaded and unzipped the NDK in home directory then your export command will look something like this: “#export PATH=$PATH:~/android-ndk-r19c“. Additionally you can add this command in ~/.bashrc to get android ndk path setup when you start terminal.
  • Next, create a directory in home directory called HelloWorldLib. Change directory to HelloWorldLib and make another directory here called jni. Change directory to jni and make another directory here called include. At this point you should have ~/HelloWorldLib/jni and ~/HelloWorldLib/jni/include directory.

 

Step2: Building shared library

  • Inside ~/HelloWorldLib/jni/ create a file called HelloWorldNative.c, Android.mk and inside ~/HelloWorldLib/jni/include/ create a file HelloWorldNative.h
  • Copy the below content into each of the file:
  • HelloWorldNative.c:
#include <jni.h>
#include “include/HelloWorldNative.h”
JNIEXPORT jstring JNICALL Java_com_example_helloso_HelloWorldLib_stringFromJNI(JNIEnv *env, jobject object) {
return (*env)->NewStringUTF(env, “Hello from C”);
}
  • HelloWorldNative.h:
JNIEXPORT jstring JNICALL Java_com_example_helloso_HelloWorldLib_stringFromJNI(JNIEnv *env, jobject object)
  • Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := HelloWorldNative.c
include $(BUILD_SHARED_LIBRARY)
  • If you want to use static library then replace the line “include $(BUILD_SHARED_LIBRARY)” to “include $(BUILD_STATIC_LIBRARY)”. But for this tutorial we are going to use shared library only.
  • At this point we are ready to create shared library. To create shared library run “ndk-build” command inside ~/HelloWorldLib/ directory. This command should create libs and obj directory inside ~/HelloWorldLib/. Inside libs directory architecture specific folders will have libhelloworld.so.

 

Step3: Using shared library

  • Open android studio and create an empty activity project “helloso” with native c/c++ support. This project should have the following package name “com.example.helloso”
  • Navigate to the app\src\main directory of your android studio project and create a folder called jniLibs
  • Next, copy all the folders inside the libs directory (generated from the previous step) in jniLibs
  • In the android studio expand the cpp tab and right click and select New>C/C++ Header File
  • Name the header file “HelloWorldNative.h” and copy paste the following line in it:
    • JNIEXPORT jstring JNICALL Java_com_example_helloso_HelloWorldLib_stringFromJNI(JNIEnv *env, jobject object)
  • Edit CMakeLists.txt and add the following lines:
    • add_library(helloworld SHARED IMPORTED)
      set_target_properties(helloworld PROPERTIES IMPORTED_LOCATION
              ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libhelloworld.so)
  • Next create a Java class called HelloWorldLib and copy/paste the following code:
    • package com.example.helloso
      
      import android.util.Log;
      
      public class HelloWorldLib {
      
      public HelloWorldLib() {
      
       }
      
       static {
       System.loadLibrary("helloworld");
       }
      
       public void this_is_a_test() {
       Log.d("Shared library: ", stringFromJNI());
       }
      
       private native String stringFromJNI();
      
      
      }
  • At this point we are set to call our native function written in C. Go to the MainActivity and add following lines in the onCreate method:
    • HelloWorldLib hwl = new HelloWorldLib();
      hwl.this_is_a_test();
  • Run your project and you should be able to see the message “Hello from C” in logcat.

Leave a Reply