使用JNI从C++调用JAVA方法,没有参数

PRN*_*ios 5 c++ java java-native-interface android jvm

请耐心等待,我是一名iPhone开发人员,这整个Android让我感到困惑.

我有一些从cocos2d-x CCMenuItem调用的c ++方法.因此,根据文档,我无法发送任何参数.

我需要用android浏览器打开一个url,这需要我调用一个JAVA函数来启动一个新的intent.

我知道我需要创建一个VM,但下面的代码给出了错误:

jni /../../ Classes/OptionsScene.cpp:184:错误:未在此范围内声明'JNI_CreateJavaVM'

我正在看这个帖子:在Android中从c ++调用java方法

但他使用参数,我不能这样做.而且我不知道他们的代码中有哪些内容可以自己创建.

我不知道'Find Class'方法中的字符串应该是什么.此外,我认为在我需要调用的每个方法中创建一个新的VM实例是非常糟糕的.我如何创建一个作为单身人士全面使用?

这是我的菜单项调用的c ++代码:

#include <jni.h>
...
JavaVM *vm; // Global
...
void OptionsScene::website(){
JNIEnv *env;
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.ignoreUnrecognized = 1;

jint result = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); // This line still errors

jclass clazz = env->FindClass("com/prndl/project/WebExecute");
jmethodID method = env->GetMethodID(clazz, "website", "(Ljava/lang/String;)V");
env->CallVoidMethod(NULL,method);

vm->DestroyJavaVM();
Run Code Online (Sandbox Code Playgroud)

这是我需要调用的JAVA方法:

public class WebExecute extends Activity{
    public void website(){
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
        startActivity(browserIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)

老实说,我正在努力解决这个问题,任何帮助都表示赞赏.谢谢.

Qua*_*nic 1

有很多事情...

  1. 考虑到声明JNIEnv* env;,并且考虑到您使用的是 C++,您可以将其用作env->FindClass(someString)而不是您的做法。如果是 C,你会使用FindClass(env, someString),但在 C++ 中,你会使用env->FindClass(someString).
  2. 要使用的字符串FindClass是完全限定路径名,但作为/分隔符而不是. 例如,如果该类Foo位于 package 中bar.baz.quux,则完全限定名称为bar.baz.quux.Foo,您要赋予的字符串FindClassbar/baz/quux/Foo
  3. 每个 C++ 进程只能创建一个 JVM。我很确定您需要一次性创建一个 JVM。因此,您需要将 设为JavaVM* vm全局变量(或者至少位于需要使用的所有内容可访问的地方)。与调用线程相同的 C++ 线程中的所有内容都JNI_CreateJavaVM()将使用JNIEnv *由该调用填充的 。每个其他线程想要使用 JVM 需要调用AttachCurrentThread它将将该线程绑定到 JVM 并为该线程填写一个新的有效值。 JNIEnv *
  4. 您是否仔细检查了编译器/IDE 设置以确保JDK_HOME/include目录(包含jni.h)位于包含搜索路径中?目录是否相同(或者在 Android JDK 中调用的JDK_HOME/include/android任何操作特定目录)?JDK_HOME/include

The JNI book是一个非常有用的资源

但阅读时要小心,因为有些示例是 C 语言,有些是 C++ 语言,因此请确保您了解调用约定的不同之处。

  • `website` 方法没有参数,因此类型签名应该是 `"()V"` 而不是 `"(Ljava/lang/String;)V"` (2认同)