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内核剖析》
posted @ 2021-03-04 17:13  我热爱的  阅读(524)  评论(0)    收藏  举报