在JNI函数(Android)之外从C调用java中的函数? [英] Call a function in java from C outside of a JNI function (Android)?

查看:404
本文介绍了在JNI函数(Android)之外从C调用java中的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Android中的JNI从我的C代码调用Java函数,但我处于一种有点尴尬的境地。

I'm trying to call a Java function from my C code using the JNI in Android, but I'm in a somewhat awkward situation.

我的C代码正在传递给库的回调中的JNI函数之外执行。

My C code is being executed outside of a JNI function in a callback that is passed to a library.

以下是java代码的示例

Here is an example of the java code

package com.my.java.package;

class MyClass {
    public function handleData(byte[] data) {
        doSomethingWithThisData(data);
    }
}

以下是C代码的示例

void handleData(uint8_t *data, size_t len) {
    // I need to call handleData in my java
    // class instance from here, but i have
    // no access to a JNIEnv here.

    // I don't think I can create one, since 
    // it has to be the same object that's 
    // sending JNI calls elsewhere.
}

. . . 

myCLibInstance.callback = handleData;

现在只要C Lib做了它需要做的事情,它就会触发回调。但我无法将其发送回java类来处理数据。

Now whenever the C Lib does what it needs to do, it will trigger the callback. But I have no way to send it back to the java class to handle the data.

推荐答案

在某些版本的Android NDK上,可以使用 JNI_GetCreatedJavaVMs 获取当前的VM ..但是,更好的选择是覆盖 JNI_OnLoad 并将VM保存在那里。使用任何一种方法,一旦你拥有了VM,就可以附加到当前线程并调用函数..

On some version of the Android NDK, JNI_GetCreatedJavaVMs could be used to get the current VM.. however, the better option is to override JNI_OnLoad and save the VM there. Using either method, once you have the VM, you can attach to the current thread and get call the function..

extern jint JNI_GetCreatedJavaVMs(JavaVM **vm, jsize size, jsize *size2);

static JavaVM *jvm = NULL;


static jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    jvm = vm;
    JNIEnv *env = NULL;

    if (jvm && (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6) == JNI_OK)
    {
        return JNI_VERSION_1_6;
    }
    return -1;
}

JavaVM* getJavaVM() {
    if (jvm)
    {
        return jvm;
    }

    jint num_vms = 0;
    const jint max_vms = 5;
    JavaVM* vms[max_vms] = {0};
    if (JNI_GetCreatedJavaVMs(vms, max_vms, &num_vms) == JNI_OK)
    {
        for (int i = 0; i < num_vms; ++i)
        {
            if (vms[i] != NULL)
            {
                return vms[i];
            }
        }
    }
    return NULL;
}

 void handleData(uint8_t *data, size_t len) {
    JavaVM *jvm = getJavaVM();

    if (jvm)
    {
        JNIEnv *env = NULL;
        if ((*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL)  == JNI_OK)
        {
            if (env)
            {
                //Call function with JNI..
            }

            (*jvm)->DetachCurrentThread(jvm);
        }
    }
}

这篇关于在JNI函数(Android)之外从C调用java中的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆