Android NDK JNI using C++ Programming Tutorial
Mostly we develop an android application by using SDK which is java programming language. Other than that, NDK is very important for us to develop some specific features such as OpenGL in the android application. It is written in C and C++ programming language which is more powerful than Java programming language. Native C/C++ perform much faster than Java because it can manage memory and bytes/bits usage. In order to use it, we need to use Android NDK JNI interface translate to readable form in java and compile the .so library. In this tutorial, I will teach you how to compile the so library and how to use C/C++ programming language in the android application.
Creating a New Project
1. Open Android Studio IDE in your computer.
2. Create a new project and Edit the Application name to “NDKExample”.
(Optional) You can edit the company domain or select the suitable location for current project tutorial. Then click next button to proceed.
3. Select Minimum SDK (API 15:Android 4.0.3 (IceCreamSandwich). I choose the API 15 because many android devices currently are support more than API 15. Click Next button.
4. Choose “Empty Activity” and Click Next button
5. Lastly, press finish button.
Note : You must download NDK package in the SDK Manager to proceed.
Setup External Tools
In your android studio menu go to File > Settings. Expand the Tools section you will see “External Tools” and Click it. After that create two external tools which are javah and ndk-build.
Click the Plus(+) button to create a new external tool. Below are my javah and ndk-build settings, you can refer it and write it in your external tools settings.
Add a java class for Java Native Interface
Right click package name > new > Java class and name it as “TestNDK“. This class will add static and load the library which name is “MyLibrary”. The library name is followed by the so file, we will compile .so file later. And the native method is to get the method from the C and C++ source code.
Edit TestNDK.java class
Go to the file and copy the following code in your class.
package com.example.questdot.ndkexample; /** * Created by HP on 17/7/2016. */ public class TestNDK { static{ System.loadLibrary("MyLibrary"); } public native String getNDKString(); }
Edit build.gradle (Module:app)
Add ndk and sourceSets.main in the defaultConfig. NDK is to specific what module name you use, for example our module name will be MyLibrary. The moduleName will follow by the C or C++ files so we will create later. In SourceSets.main section the jni.srcDirs =[] mean disable auto and jniLibs.src are specify which jni library located.
defaultConfig { applicationId "com.example.questdot.ndkexample" minSdkVersion 15 targetSdkVersion 24 versionCode 1 versionName "1.0" ndk{ moduleName "MyLibrary" } sourceSets.main { jni.srcDirs = [] jniLibs.srcDir "src/main/libs" } }
Edit gradle-properties
You will occur an error if you do not add the following code
android.useDeprecatedNdk=true
Add a JNI folder
From Android navigate to Project Files, after that right click main folder > New > Folder > JNI Folder. You will see a new JNI folder was added in.
Add new C++ files
Right click your folder name jni > New > C++ class and name it as “MyLibrary“. This name must be same as ModuleName in build.gradle.
Generate Header files for MyLibrary.cpp
Go to your java folder and Right click TestNDK.java class > NDK >javah. It will automatically create a header file in your jni folder.
For example, It will look like this.
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_example_questdot_ndkexample_TestNDK */ #ifndef _Included_com_example_questdot_ndkexample_TestNDK #define _Included_com_example_questdot_ndkexample_TestNDK #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_questdot_ndkexample_TestNDK * Method: getNDKString * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_questdot_ndkexample_TestNDK_getNDKString (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
Edit MyLibrary.cpp files
Copy the method header from Auto-generated header files and paste it into this file. After that, add the parameter variable and return a value by using C++ code style. You must include the header file.
#include "com_example_questdot_ndkexample_TestNDK.h" JNIEXPORT jstring JNICALL Java_com_example_questdot_ndkexample_TestNDK_getNDKString (JNIEnv* env, jobject obj){ return (*env).NewStringUTF("My Jni Text"); }
Create two MakeFiles .mk
Right click jni folder > New > File and name it to Android.mk. Add the following code to your file.
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := MyLibrary LOCAL_SRC_FILES := MyLibrary.cpp include $(BUILD_SHARED_LIBRARY)
Create another makefile which names it to Application.mk then add the following code.
APP_MODULES := MyLibrary APP_ABI := all
Compile .so files (Shared Library)
Right-click main folder > NDK > ndk-build. You will see new so files will appear in your libs folder as the picture below. The folders separate by different CPUs name.
Edit activity_main.xml layout
Add id in the textview so we can use it later. You can copy and paste the following example.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="//schemas.android.com/apk/res/android" xmlns:tools="//schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.questdot.ndkexample.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" android:text="Hello World!" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
Edit MainActivity.java class
Go to the class and set the textview to the string get from ndk.
package com.example.questdot.ndkexample; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity { TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView=(TextView)findViewById(R.id.textView); TestNDK testNDK= new TestNDK(); textView.setText(""+testNDK.getNDKString()); } }
Run your project
Yes, you have complete the NDK tutorial and now you can start it to see what will happen on your device.
First of all thanks for this tutorial can you explain me how i can use lame library like this .