If you need to link c++ native codes to android studio project, please follow these steps:
It’s easier to understand if you create a native c++ project to see its structure, see: https://developer.android.com/studio/projects/add-native-code
Part I: change settings
-
Create folder “cpp“ in src/main, put native c++ codes here.
-
Create file “CMakeLists.txt“ in src/main/cpp. Please refer (https://skillion.atlassian.net/wiki/spaces/HAWK/pages/702906421/CMakeLists.txt ) for more details.
-
Add NDK path in local.properties.
-
Two parts in build.grandle need to be changed:
In android, add:
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
In android.defaultConfig, add:
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
arguments "-DANDROID_ARM_NEON=TRUE",'-DANDROID_STL=c++_shared'
}
}
Part II: Edit Code
-
In src/main/cpp, add “native-lib.cpp“. In this file you need to create interfaces for c++ functions.
One example, if we have a helloworld.cpp in src/main/cpp:
#include <iostream>
#include "HelloWorld.h"
using namespace std;
string print() {
return "Hello World!";
}
Then add the interface of print() to native-lib.cpp:
#include <jni.h>
#include <string>
#include "HelloWorld.h"
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_cpptest_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
string helloworld = print();
return env->NewStringUTF(helloworld.c_str());
}
-
You may notice the method name of this interface, it is merged by package name (Java_com_example_cpptest), the name of the Java file which invokes this c++ function (MainActivity.java), and an interface name which your java file will incoke (stringFromJNI).
-
In this interface, we need to convert the c++ function output to c formation.
2. In MainActivity.java, where we want to invoke c++ function, we need to change 3 things:
-
Tell complier you will use the c++ lib:
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
-
Declare c++ interface as Java formation:
public native String stringFromJNI();
-
Using this declared function:
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
If you also need to link some c++ libraries, please follow this step (take opencv as example):
change settings:
You also need to change settings in previous Part I for native c++ code
-
Download OpenCV-android-sdk.
-
In your project, create src/main/jniLibs folder.
-
Copy OpenCV-android-sdk\sdk\native\libs to jniLibs. There’re four folders in it, and each one contains a libopencv_javax.so. These files are for opencv to run on different platforms. x may be 3 or 4.
-
Change CMakeList.txt. Please refer (https://skillion.atlassian.net/wiki/spaces/HAWK/pages/702906421/CMakeLists.txt ) for more details.
-
One part in build.grandle need to be changed:
In android, add:
packagingOptions {
pickFirst 'lib/x86_64/libopencv_java4.so'
pickFirst 'lib/x86/libopencv_java4.so'
pickFirst 'lib/arm64-v8a/libopencv_java4.so'
pickFirst 'lib/armeabi-v7a/libopencv_java4.so'
}
You may need change 4 to 3.