在java类里写个native方法html
public class Java2CJNI {
public native String java2C();
}
复制代码
javah 生成jni样式的标准头文件java
切换到src/main/java
目录下执行android
javah -d ../jni ndkold.study.com.ndkolddemo.Java2CJNI
复制代码
-d ../jni 指定输出路径为:当前目录的父目录下的jni目录 ndkold.study.com.ndkolddemo.Java2CJNI这是包含native方法的那个类c++
3.执行完后生成了jni目录及头文件git
这个就是java与native方法进行交互的接口github
˙注意这里新建的是c++代码,c++代码对应下面的代码bash
//引入刚才生成的头文件
#include "ndkold_study_com_ndkolddemo_Java2CJNI.h"
//复制头文件里的要实现的方法名及其参数
JNIEXPORT jstring JNICALL
Java_ndkold_study_com_ndkolddemo_Java2CJNI_java2C(JNIEnv *env, jobject instance) {
// 实现这个方法,返回一个字符串
return env->NewStringUTF("Hello from C++");
}
复制代码
你也能够写个.c源文件,其对应代码为app
//引入刚才生成的头文件
#include "ndkold_study_com_ndkolddemo_Java2CJNI.h"
//复制头文件里的要实现的方法名及其参数
JNIEXPORT jstring JNICALL
Java_ndkold_study_com_ndkolddemo_Java2CJNI_java2C(JNIEnv *env, jobject instance) {
// 实现这个方法,返回一个字符串
return (*env)->NewStringUTF(env, "Hello from C");
//注意这里是(*env),并且须要传递一个参数(env)
}
复制代码
首次接触jni可忽略下面的解释,知道怎么用就行,之后再慢慢研究ide
说明:c与c++就这点区别,查看jni.h文件,发如今c里的JNIEnv是结构体指针JNINativeInterface*的别名,因此JNIEnv *env至关于二级指针,如今要调用JNINativeInterface*里的方法,要用(*env)->xxxui
在c++里JNIEnv是_JNIEnv的别名,在_JNIEnv内部里有个属性为结构体指针JNINativeInterface*,而后他把全部c里的方法都从新定义了一下,定义方式就是经过JNINativeInterface*调了一遍全部c里的方法,并且把JNINativeInterface*的对象以this方式传递进去了,可见这里的JNIEnv *env是一个一级指针,因此经过env就能够直接调用对应的方法了(有点绕)
![]()
![]()
![]()
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugNdk'.
> Error: Your project contains C++ files but it is not using a supported native build system.
Consider using CMake or ndk-build integration. For more information, go to:
https://d.android.com/r/studio-ui/add-native-code.html
Alternatively, you can use the experimental plugin:
https://developer.android.com/r/tools/experimental-plugin.html
复制代码
在AndroidStudio3.2.1版本如下,是其余处理方式,见下文 如何解决Your project contains C++ files but it is not using a supported native build system, 可是我用的是3.2.1版本,按照上述处理仍是不行的,要参考这篇文章android Studio(3.2.1) NDK配置
找到Android.mk文件,在build/intermediates/ndk/目录里
复制到这里,jni/
defaultConfig {
...
ndk {
moduleName "Java2C"
//so文件名,若是这里配置了so文件名字,
//记得更改Android.mk里的LOCAL_MODULE :字段为 LOCAL_MODULE := Java2C
abiFilters "armeabi", "armeabi-v7a", "x86" //指定so文件所支持的CPU类型,若是不写的话,会生成全部的CPU类型的so文件
}
}
复制代码
android {
...
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"//指定Android.mk路径
}
}
}
复制代码
至今生成了libJava2C.so文件
9.调用native方法
public class Java2CJNI {
// 先加载so文件,注意这里的libname是Java2C,不是 libJava2C.so
// 这个libname是Android.mk里的 LOCAL_MODULE := Java2C 字段控制的,注意必定要一致的
static {
System.loadLibrary("Java2C");
}
public native String java2C();
}
复制代码
至此,java经过jni调用C++ 成功了
若是你没成功,极可能是这几处不一致
这篇文章在AndroidStudio版本3.2.1上不适用,适用于更早期的版本
这篇文章适用于AndroidStudio版本3.2.1以上