上一篇,我們講到了JNI的靜態(tài)注冊,沒看過的,按需查看
【進階解密】JNI初學篇(一)-靜態(tài)注冊 http://www.itdecent.cn/p/993c8f2d6857
今天我們講下動態(tài)注冊
主要步驟為:
1、java中定義Native方法
2、編寫C/C++文件,實現(xiàn)jni接口方法,以及JNI_OnLoad方法
3、編譯so庫
4、java加載so庫,調用native方法
1、新建java類,定義Native方法getHello
package jni.com.cj.constom.jnitest;
/*
* 動態(tài)注冊方式
* */
public class JNITest2 {
static {
System.loadLibrary("mgjnitest2");
}
public static native String getHello();
}
2、新建文件jni_com_cj_constom_jnitest_JNITest.c ,實現(xiàn)jni接口方法,以及JNI_OnLoad方法
注意:C語言和C++的實現(xiàn)存在一些差異,GetEnv、FindClass、RegisterNatives方法參數(shù)有差異,若要用C++實現(xiàn),就自行搜索下其他文章哈,文章很多~
下面是C語言的實現(xiàn)方式
#include <jni.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
JNIEXPORT jstring JNICALL get_Hello(JNIEnv *env, jclass type) {
return (*env)->NewStringUTF(env, "Hello from JNI 動態(tài)注冊測試!");
}
static JNINativeMethod g_methods[] = {
{"getHello",//java定義的native方法名
"()Ljava/lang/String;", //()表示無參數(shù);Ljava/lang/String表示返回String類型
(void *) get_Hello //JNI中實現(xiàn)的方法名
}
};
JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **)&env,JNI_VERSION_1_6) != JNI_OK) {
return JNI_FALSE;
}
const char *class_path = "jni/com/cj/constom/jnitest/JNITest2";//這里對應native的java類
jclass javaClass = (*env)->FindClass(env,class_path);
if (javaClass == NULL) {
return JNI_FALSE;
}
int method_count = sizeof(g_methods) / sizeof(g_methods[0]);
if ((*env)->RegisterNatives(env,javaClass, g_methods, method_count) < 0) {
return JNI_FALSE;
}
return JNI_VERSION_1_6;
}
3、分別創(chuàng)建Android.mk、Application.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mgjnitest2
LOCAL_SRC_FILES := jni_com_cj_constom_jnitest_JNITest.c
include $(BUILD_SHARED_LIBRARY)
#APP_ABI := armeabi armeabi-v7a arm64-v8a x86
APP_ABI := all
APP_OPTIM := release
## 引用靜態(tài)庫
APP_STL := stlport_static
#NDK_TOOLCHAIN_VERSION=4.8
#APP_PLATFORM := android-14
APP_PLATFORM := android-16
APP_ALLOW_MISSING_DEPS=true
4、主項目點擊事件代碼:
public void getJNIValue2(View view) {
String test = JNITest2.getHello();
Toast.makeText(getApplicationContext(), "value=" + test, Toast.LENGTH_SHORT).show();
}
測試結果:

image.png