1. Download ndk
ndk can be downloaded directly through sudio (tools - > Android - > SDK Manager - > SDK tools to download cmake and ndk)
Or directly to AndroidDevTools Download and configure the environment of the ndk like the sdk.
2. Check Include C++ Support when creating a new Android project. It is estimated that it is also the main way for Android to push. I downloaded the latest ndk through Android studio, and the following error occurred when compiling
* What went wrong:
A problem occurred configuring project ':app'.
> executing external native build for cmake F:\github\JniTest\app\CMakeLists.txt
Discover by viewing the output information of the grade console
Configuration on demand is an incubating feature.
CMake Error at C:/Users/xxx/AppData/Local/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake:312 (message):
Invalid Android ABI: mips64. (MIPS and MIPS64 are no longer supported.)
Call Stack (most recent call first):
C:/Users/xxx/AppData/Local/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/CMakeDetermineSystem.cmake:98 (include)
CMakeLists.txt
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
FAILURE: Build failed with an exception.
However, the latest ndk downloaded does not support mips64, mips and armeabi. If you need to compile these so, you can download the lower version of ndk. If you do not need these versions of so, you can specify the required so type in build.gradle. The configuration under the defaultConfig node is as follows:
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "com.jason.jnitest"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
ndk {
abiFilters "armeabi-v7a", "x86" //Configure the required so. If it is not configured, it will be generated by default"armeabi-v7a", "x86"
}
}
}
In this way, you can solve the problem of compiling so errors. If there are other compilation errors, you can view the specific build failed reasons according to the output information of the grade console. In addition, when implementing the corresponding function in. cpp, you need to add extern "C" in front of the function to avoid java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String Mistake
#include <jni.h>
#include <string>
#include "android/log.h"
static const char *TAG = "jason";
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
extern "C"
JNIEXPORT void JNICALL
Java_com_jason_jni_demo_MainActivity_sayHelloToC(JNIEnv *env, jclass type, jstring str_) {
const char *str = env->GetStringUTFChars(str_, 0);
// TODO
LOGE("str :%s ", str);
env->ReleaseStringUTFChars(str_, str);
}
//java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.jason.jni.demo.MainActivity.stringFromJNI()
extern "C" //The above error will appear in comment line
JNIEXPORT jstring JNICALL
Java_com_jason_jni_demo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
Or in the following format:
#include <jni.h>
#include <string>
#include "android/log.h"
static const char *TAG = "jason";
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
extern "C" { //The implemented functions are placed in this label
JNIEXPORT void JNICALL
Java_com_jason_jni_demo_MainActivity_sayHelloToC(JNIEnv *env, jclass type, jstring str_) {
const char *str = env->GetStringUTFChars(str_, 0);
// TODO
LOGE("str :%s ", str);
env->ReleaseStringUTFChars(str_, str);
}
JNIEXPORT jstring JNICALL
Java_com_jason_jni_demo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
}