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

Please bear with me, I am an iPhone developer and this whole android this confuses me a bit.

I have some c++ methods that are called from a cocos2d-x CCMenuItem. Therefore I cannot send any parameters, according to the docs.

I need to open a url with the android browser which will require me to call a JAVA function to start a new intent.

I understand that I need to create a VM, however the below code gives me the error:

jni/../../Classes/OptionsScene.cpp:184: error: 'JNI_CreateJavaVM' was

not declared in this scope

But he uses parameters, and I can't do that. And I don't see where those are in his code to just make them myself.

I don't know what the string should be in the 'Find Class' method.

Also, I assume it is pretty terrible to create a new VM instance in every method I need to call. How would I create one as a singleton to use across the board?

This is my c++ code called by my menu item:

#include

...

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();

And this is the JAVA Method that I need to call:

public class WebExecute extends Activity{

public void website(){

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));

startActivity(browserIntent);

}

}

Honestly, I am struggling with this, any help is appreciated. Thanks.

解决方案

A number of things...

Given the declaration JNIEnv* env;, and given that you're in C++, you use it as env->FindClass(someString), not how you're doing it. If it was C you'd use FindClass(env, someString) but in C++ you use env->FindClass(someString).

The string to use in FindClass is the fully qualified path name but with / as the delimiter instead of . For example, if the class is Foo in package bar.baz.quux, the fully-qualified name is bar.baz.quux.Foo and the string you'd give to FindClass is bar/baz/quux/Foo.

You can only create one JVM per C++ process. I'm pretty sure you need to create a single JVM one time. You will therefore need to have the JavaVM* vm be a global variable (or at least be somewhere accessible to everything that needs to use. Everything in the same C++ thread as the thread that called JNI_CreateJavaVM() will use the JNIEnv * that gets filled in by that call. Every other thread that wants to use the JVM needs to call AttachCurrentThread which will bind that thread to the JVM and fill in a new JNIEnv * valid for that thread.

Have you double-checked your compiler/IDE settings to make sure that the JDK_HOME/include directory (which contains jni.h) is in the includes search path? Same for the JDK_HOME/include/android directory (or whatever the operating specific directory in JDK_HOME/include is called in a Android JDK)?

A very useful resource is The JNI book

But be careful while reading it because some examples are in C and some are in C++, so make sure you understand how the calling conventions differ.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值