AndroidStudio jni C++与Java互相调用

一、 Java调用C++

C++注册Native方法后,记得在Java类中加载你对应的C++库。

static {
System.loadLibrary(“native-lib”);
}

1.静态注册Native函数

在Java类中声明一个native方法,AndroidStudio就会提醒该方法未定义,把鼠标放上去就会显示生成JNI function:
在这里插入图片描述

点击会在native-lib.cpp中自动产生对应的native方法,在方法里面做实现就可以了:
在这里插入图片描述

2.动态注册

同样在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 J
float F
double D
L全限定名;比如String, 其签名为Ljava/lang/util/String;
数组 [类型签名, 比如 [B

3、className 是你要注册的Java类,注意格式。

二、C++调用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方法。

猜你喜欢

转载自blog.csdn.net/qq_36383272/article/details/126369969