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

问题描述 投票:0回答:3

请耐心听我说,我是一名 iPhone 开发人员,整个 Android 这让我有点困惑。

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

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

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

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

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

但是他用参数,我做不到。而且我不知道这些代码在他的代码中的什么位置,只能自己制作。

我不知道“查找类”方法中的字符串应该是什么。 另外,我认为在我需要调用的每个方法中创建一个新的虚拟机实例是非常糟糕的。我将如何创建一个作为单例以供全面使用?

这是我的菜单项调用的 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);
    }
}

老实说,我正在为此苦苦挣扎,非常感谢任何帮助。谢谢。

java android c++ jvm java-native-interface
3个回答
4
投票

如果您正在了解如何调用不接受任何参数的 java 方法,格式为

jmethodID mid = env->GetStaticMethodID(myClass, "myMethod", "()V");

()
是告诉它不接受任何参数的方式。

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


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。因此,您需要将
  4. JavaVM* vm
     设为全局变量(或者至少位于需要使用的所有内容都可访问的地方)。与调用 
    JNI_CreateJavaVM()
     的线程位于同一 C++ 线程中的所有内容都将使用获得的 
    JNIEnv *
    由该调用填充的每个其他想要使用 JVM 的线程都需要调用 
    AttachCurrentThread
    ,它将将该线程绑定到 JVM 并填充对该线程有效的 
    new JNIEnv *
    您是否仔细检查过编译器/IDE 设置以确保
  5. JDK_HOME/include
  6. 目录(包含
    jni.h
    )位于包含搜索路径中?对于
    JDK_HOME/include/android
    目录(或者在 Android JDK 中调用
    JDK_HOME/include
    中的任何操作特定目录)也是如此吗?
    
    
    
  7. 一个非常有用的资源是
JNI 书

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


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.