代码之家  ›  专栏  ›  技术社区  ›  Ajay Gaonkar

从本机c代码(JNI)为java中的回调函数传递多个参数

  •  0
  • Ajay Gaonkar  · 技术社区  · 7 年前

    下面的代码从本机c代码调用java中的回调函数,并将一些字符串数据作为参数传递。

    本机C层

    jmethodID statusId = env->GetMethodID(pctx->jniHelperClz, "CallbackHandler", "(Ljava/lang/String;)V");
    jstring string_data = env->NewStringUTF((const char*)"SOME_STRING_DATA");
    env->CallVoidMethod(pctx->jniHelperObj, statusId, string_data);
    env->DeleteLocalRef(string_data);
    

    Android/Java(回调处理程序)

    @Keep
    private void CallbackHandler(String string_data) {
        // Some Code
    }
    

    除了字符串之外,我还想传递一个int类型的数据。我的java回调处理程序如下所示。为了支持两个参数,我应该在本机层中更改什么。

    @Keep
    private void CallbackHandler(String string_data, int int_data) {
        // Some Code
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Sergei Bubenshchikov    7 年前

    您需要将方法签名从 (Ljava/lang/String;)V (Ljava/lang/String;I)V :

    jmethodID statusId = env->GetMethodID(pctx->jniHelperClz, “CallbackHandler”, "(Ljava/lang/String;I)V”);
    

    此外,您使用 DeleteLocalRef() 不正确的方式。此方法用于删除通过创建的本地引用 NewLocalRef() 但是 NewStringUTF() 而不是创建它们。方法 NewStringUTF() 创造 jstring 对象,该对象位于垃圾收集器控制下的java堆中。您不需要手动删除此项。

    注意:

    本地引用在本机方法调用期间有效。他们是 自动释放 在本机方法返回后。每个本地引用都会消耗一些Java虚拟机资源。程序员需要确保本机方法不会过度分配本地引用。虽然本地方法返回Java后会自动释放本地引用,但过度分配本地引用可能会导致VM在执行本地方法期间耗尽内存。

    你需要使用 DeleteLocalRef() 立即删除大型对象(例如,在循环中)。