Android 本机 Activity - 调用 Java 方法

Android Native Activity - Call Java method

我已经尝试了一段时间从 c++ 调用 java 方法,我能够使用 Activity class 成功完成,但使用 NativeActivity,调用CallVoidMethod时崩溃。 GetMethodID 是能够找到它的,它 returns 一个地址。 env 和 vm 对象是有效的并且是从 android_main() 填充的。有没有可能它根本无法与原生 activity class 一起使用?

Cpp:(已编辑)

void SendNotification() {

    JavaVM* lJavaVM = main_activity->vm;
    JNIEnv* lJNIEnv = main_activity->env;

    JavaVMAttachArgs lJavaVMAttachArgs;
    lJavaVMAttachArgs.version = JNI_VERSION_1_6;
    lJavaVMAttachArgs.name = "NativeThread";
    lJavaVMAttachArgs.group = NULL;

    jint lResult = lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
    if (lResult == JNI_ERR)
        return;

    jobject lNativeActivity = main_activity->clazz;
    jclass ClassNativeActivity = lJNIEnv->GetObjectClass(main_activity->clazz);
    jmethodID _method = lJNIEnv->GetMethodID(ClassNativeActivity, "SendNotification", "()V");

    lJNIEnv->CallVoidMethod(lNativeActivity, _method);

    lJavaVM->DetachCurrentThread();
}


Java:

package com.thor.kalen;

import android.app.AlertDialog;
import android.app.NativeActivity;
import android.os.Bundle;

public class MainActivity extends NativeActivity
{
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    } // End of public void onCreate(Bundle savedInstanceState)

    public void SendNotification() {
        new AlertDialog.Builder(this).setTitle("Alert").setMessage("").setNeutralButton("Close", null).show();
    }
}

com.thor.kalen.MainActivity.SendNotification() Java 方法应该为 class 的 jobject 调用com.thor.kalen.MainActivity,不是这个对象的 jclass:它不是 static方法:

main_activity->env->CallVoidMethod(main_activity.clazz, _method)

注意native_activity.h中的注释:

/**
 * The NativeActivity object handle.
 *
 * IMPORTANT NOTE: This member is mis-named. It should really be named 
 * 'activity' instead of 'clazz', since it's a reference to the
 * NativeActivity instance created by the system for you.
 * 
 * We unfortunately cannot change this without breaking NDK
 * source-compatibility.
*/
jobject clazz;

此外,您只能从主 (UI) 线程 show() AlertDialog。您的 C++ 代码建议您从后台线程执行。

如果这段代码在主线程上执行,那么

main_activity->vm->DetachCurrentThread()

应该删除。 AttachThread() 也可以删除,但在已附加的线程上调用时它是一个 NOP。