android - 如何从 NDK C++ 线程调用 Java API?

标签 android java-native-interface

我想从 NDK C++ 线程调用 Java API,但 env->FindClass() 返回 0。但是当我在主线程中调用 Java API 时,它运行良好。我已经在线程中调用了 AttachCurrentThread(),有人可以帮助我吗?

这是源代码:

Java 代码:

public class simple_test extends Activity {
    ...
    // This functin will be called in C++
    public void PrintNdkLog(String slog) {
        Log.e(logTagNDK, slog);
        return;
    }
}

C++ 代码:

static JavaVM* g_JavaVM = NULL;

jobject getInstance(JNIEnv *env, jclass obj_class)
{
    jmethodID  c_id = env->GetMethodID(obj_class, "<init>", "()V");
    jobject obj = env->NewObject(obj_class, c_id);
    return obj;
}

// JNI OnLoad
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    g_JavaVM = jvm;
    return JNI_VERSION_1_6;
}

// Call JAVA API "PrintNdkLog" in this function
void PrintNdkLog(char *lpLog)
{
    if (g_JavaVM == NULL)
        return;

    JNIEnv *env = NULL;
    g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6);
    if (env == NULL)
        return;

    jclass cls = env->FindClass("com/myndk/simple_test");
    if (cls != 0) // **cls will be 0 when PrintNdkLog() is called in thread**
    {
        LOGE("FindClass error %p", cls);
    }
    else
    {
        jmethodID mid;
        jobject obj;
        obj = getInstance(env, cls);
        mid = env->GetMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V");
        if (mid != 0)
        {
            jstring jstrMSG = env->NewStringUTF(lpLog);
            env->CallVoidMethod(obj, mid, jstrMSG);
        }
    }
}

// Call JAVA API in thread
static void* thread_test(void* ptr)
{
    JNIEnv *envLocal;
    int status = g_JavaVM->GetEnv((void **) &envLocal, JNI_VERSION_1_6);
    if (status == JNI_EDETACHED)
    {
        status = g_JavaVM->AttachCurrentThread(&envLocal, NULL);
        if (status != JNI_OK)
            LOGE("AttachCurrentThread failed %d",status);
    }
    PrintNdkLog("bbb"); // This JAVA callback failed, and printed "FindClass error"
}

// Create thread
int NdkThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority)
{
    PrintNdkLog("aaa"); // This JAVA callback runs well
    pthread_t pid;
    pthread_create(&pid, NULL, thread_test, pParam);
}

最佳答案

我现在已经解决了。 在 NDK 原生线程中,只能调用静态 Java API。如果你调用 env->FindClass(),它会触发一个异常。 http://android.wooyd.org/JNIExample给出了详细信息。

关于android - 如何从 NDK C++ 线程调用 Java API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8530924/

相关文章:

java - 如何从 jni 端调用 java 方法?

android - 使用android创建动态 View

java - WebView android不允许全屏

iphone - 跨平台框架是否适合将移动应用程序中的所有事情都做成原生的?

android - Android FaceDetector 的底层技术

c++ - WINAPI 消息循环让我抓狂

java - 如何在Fragment之间共享公共(public)资源?

android - 使用 onGroupExpand 获取 ExpandableListView 的扩展组 View

java - 我如何从 JBoss 中的 EJB 调用 JNI 代码

java - 为什么在 JNI 中调用纤程会在 JVM 中引发 StackOverflow?