首先下载好对应的NDK,解压目录配置到Android Studio项目下的local.properties:
ndk.dir=C\:\\Users\\aibo\\AppData\\Local\\Android\\Sdk\\ndk-bundle
sdk.dir=C\:\\Users\\aibo\\AppData\\Local\\Android\\Sdk
方式一:
新建项目时选择最后一个C++项目:
然后创建出来的项目就直接可以运行了,出来的文字就是调用c++方法得到的Hello from C++。具体解释请往下看。
方式二:
针对在创建项目时没有想到现在会用到JNI的情况。就是已有项目了。
配置比较复杂,这里用最简单粗暴的方法:通过方式一新建出来的项目,复制里面的关键文件到自己的项目下:
-
复制cpp目录以及下面的两个文件到对应目录下。
-
复制build,gradle里面的externalNativeBuild代码过去:
其实内容里面东西也不多,列出来吧:
CMakeLists.txt
(如果需要修改,就修改native-lib,或者在它的下面添加你自己的C或C++文件的名称)
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
native-lib.cpp)
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
native-lib.cpp
(可以把里面的这个方法去掉,再自己写方法,下面会解释如何写)
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_xaehu_jnidemo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
build.gradle中需要添加的代码:
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
封装实现和解释:
1、创建一个JNI工具类,作为java调用C的桥梁:
public class JniTool {
static {
System.loadLibrary("native-lib");
}
public static native String sayHello();
}
注意native关键字,表示这个方法是调用jni的方法。
2、然后这个sayHello方法是调用C里的,但是我们没有创建,所以这里会报红。我们的AS工具再这里按提示的话,他会提醒我们创建C的方法:
3、回车,它就会在native-lib.cpp文件里自动创建该方法代码:
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_xaehu_jnitest_JniTool_sayHello(JNIEnv *env, jclass type) {
// TODO
return (*env)->NewStringUTF(env, returnValue);
}
说明几点:
- #include <jni.h>是固定的。
- JNIEXPORT jstring JNICALL:主要是中间这个jstring表示该方法返回String类型,同理,int类型就是jint。具体类型可ctrl点进去看。
- 其实这个返回值和我们定义java方法也差不多,我们也可以把这行去掉,然后把下面的方法名写成 jstring Java_com_xaehu_jnitest_JniTool_sayHello(JNIEnv *env, jclass type)是同样效果
- 方法名那么那么长Java_com_xaehu_jnitest_JniTool_sayHello(JNIEnv *env, jclass type),我们拆分一下:Java_包名_类名_方法名(JNIEnv *env, jclass type[,其他参数])。包名中间用下划线隔开。
- 返回值中returnValue我们在下面定义,就是要给java返回的String值
- C/C++中没有String类型,用char*
再举个栗子,计算两个数字相加:
android代码:
public static native String numberAdd(int a,int b);
C/C++代码:
#include <jni.h>
jint Java_com_xaehu_jnitest_JniTool_numberAdd(JNIEnv *env, jclass type,jint a,jint b) {
return a + b;
}
就是这么简单。