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

时间:2012-07-04 02:27:59

标签: java android c++ jvm java-native-interface

请耐心等待我,我是一名iPhone开发者,这整个Android让我有点困惑。

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

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

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

  

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

我正在看这个帖子:Calling a java method from c++ in Android

但他使用参数,我不能这样做。我不会在他的代码中看到他们自己制作它们的位置。

我不知道'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();

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

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

老实说,我正在为此努力,任何帮助都表示赞赏。感谢。

2 个答案:

答案 0 :(得分:1)

很多事情......

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

    但是在阅读它时要小心,因为有些例子在C中,有些在C ++中,所以请确保你理解调用约定的不同。

答案 1 :(得分:1)

如果您正在研究如何调用不接受任何参数的java方法,格式为jmethodID mid = env->GetStaticMethodID(myClass, "myMethod", "()V");

()就是你怎么告诉它不接受任何参数。

V表示它返回无效。如果方法返回Ljava/lang/String;类型的对象,则应使用String