Gradle项目使用Jni
首先新建一个工程
在local.properties里面加上ndk.dir
ndk.dir=D\:\\sdk\\android-sdk_r24.4.1-windows\\ndk\\android-ndk-r17c
新建一个类,这里就叫JniManager,在里面声明native方法
public native int sum(int a ,int b);
javah生成头文件,其实生不生头文件都无所谓,头文件可以偷懒直接复制Jni方法,在JniManager的当前目录执行命令 javac -classpath.\ -h -jni JniManager.java,这里使用的是powershell,不知道为啥在studio的Terminal没效果。

在main目录新建jni文件夹,叫啥名字都无所谓,studio自带新建JNI Folder,然后新建一个cpp文件,这里就叫test.cpp,将上面生成的h文件移动到jni目录里面,将里面内容复制到test.cpp,然后新建Android.mk文件。
Android.mk内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := test.cpp
LOCAL_MODULE := nativedemo
LOCAL_CFLAGS += -Wno-unused-function
#Wno表示诊断时忽视这个警告
#遇到仅声明过但尚未定义的静态函数时发出警告。
LOCAL_CFLAGS += -Wno-unused-parameter
#从未用过的函数参数的警告。
LOCAL_CFLAGS += -Wno-unused-variable
#在本地声明但从未用过的变量的警告。
LOCAL_CPPFLAGS += -fexceptions
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
#递归编译
这里就不展开说明Android.mk了
然后引入jni里面的C++工程,选择ndk-build,选择你的mk文件就行。会自动生成代码在app的build.gradle文件里面。

下面可以在test.cpp里面写自己的逻辑了,简单示范一下
JNIEXPORT jint JNICALL Java_com_hsae_jnidemo_JniManager_sum
(JNIEnv * env, jobject object, jint a, jint b){
int result = a +b;
return result;
};
最后调用nativie方法,就ok了。这里libname要和mk文件里面的LOCAL_MODULE名称一致

C调用java
java层代码:
class:JniManager
public int speak (int name){
Log.d(TAG, "name come from native: "+name);
return name;
}
test.cpp:
JNIEXPORT jfloat JNICALL Java_com_hsae_d531mc_jni_JniManager_mult
(JNIEnv * env, jclass classes, jfloat a, jfloat b){
//cls = env->GetObjectClass(jobject) //get java object class
//javap -s JniManager.class
//同理C也可以访问JniManager中的变量,修改第二个和第三个参数就行了
mid_speak = env->GetMethodID(classes,"speak","(I)I");
//在native层构建一个对象,这里是获取构造方法
jmethodID constrocMID = env->GetMethodID(classes,"<init>", "()V");
//构建对象,无参构造
jobject jnimanager_obj = env->NewObject(classes,constrocMID);
//这里调用java方法
env->CallIntMethod(jnimanager_obj,mid_speak,6);
float result = a*b;
return result;
}
学习资料:《Android内核剖析》

浙公网安备 33010602011771号