C++注册Native方法后,记得在Java类中加载你对应的C++库。
static {
System.loadLibrary(“native-lib”);
}
在Java类中声明一个native方法,AndroidStudio就会提醒该方法未定义,把鼠标放上去就会显示生成JNI function:
点击会在native-lib.cpp中自动产生对应的native方法,在方法里面做实现就可以了:
同样在Java类中声明native方法。
声明后在native-lib.cpp中自己实现该方法。
extern "C" JNICALL void TestJni(){
}
实现后注册该方法:
static JNINativeMethod getMethods[] = {
{"nativeTestJni","()V",(void*)TestJni},
{"nativeGetOffer","()Ljava/lang/String;", reinterpret_cast<void*>(getOffer)},
};
static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* getMethods,int methodsNum){
jclass clazz;
//找到声明native方法的类
clazz = env->FindClass(className);
if(clazz == NULL){
return JNI_FALSE;
}
//注册函数 参数:java类 所要注册的函数数组 注册函数的个数
if(env->RegisterNatives(clazz,getMethods,methodsNum) < 0){
return JNI_FALSE;
}
return JNI_TRUE;
}
extern "C" jint JNIEXPORT
JNICALL JNI_OnLoad(JavaVM* jvm, void* reserved) {
JNIEnv* env = NULL;
if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
assert(env != NULL);
//注册函数 registerNatives ->registerNativeMethods ->env->RegisterNatives
const char* className = "com/begoit/testjni/MainActivity";
if(!registerNativeMethods(env,className,getMethods, sizeof(getMethods)/ sizeof(getMethods[0])))
return -1;
//返回jni 的版本
return JNI_VERSION_1_6;
}
注意:
1、 JNINativeMethod 中第一个参数为要注册的native方法的名字,要与Java类中定义的方法名一致。
2、JNINativeMethod 中第二个参数native方法的参数和返回值,括号里为参数,括号外为返回值。参数可以有多个,以分号;隔开。Java的类型对应的signature
ava 类型 类型签名
Java 类型 | 类型签名 |
---|---|
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | L |
float | F |
double | D |
类 | L全限定名;比如String, 其签名为Ljava/lang/util/String |
数组 | [类型签名, 比如 [B |
3、className 是你要注册的Java类,注意格式。
extern "C"
JNIEXPORT void JNICALL
Java_com_begoit_xiurtcserver_XiuRTCService_OnProcessCameraData(JNIEnv *env, jobject thiz) {
// TODO: implement OnProcessData()
jclass myClass = env->FindClass("com/begoit/xiurtcserver/CameraProcessor");
if (myClass == nullptr) {
LOGE("can not find CameraProcessor class");
return;
}
LOGI("find CameraProcessor class");
method = env->GetMethodID(myClass, "TestJni", "()V");
LOGI("find GetMethodID TestJni");
jclass xiurtc = env->GetObjectClass(thiz);
LOGI("GetObjectClass XiuRTCService");
jfieldID fid = env->GetFieldID(xiurtc, "cameraProcessor",
"Lcom/begoit/xiurtcserver/CameraProcessor;");
LOGI("GetFieldID cameraProcessor");
jobject camera = env->GetObjectField(thiz, fid);
LOGI("GetObjectField cameraProcessor");
env->CallVoidMethod(camera, method);
LOGI("CallVoidMethod");
}
说明:
1、我在XiuRTCService类中有一个CameraProcessor 类型的cameraProcessor;
CameraProcessor 中有个函数TestJni。
2、XiuRTCService类中定义的native方法 OnProcessCameraData。
上述函数可以实现 调用XiuRTCService中的cameraProcessor对象的TestJni方法。