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
I was looking at this thread: Calling a java method from c++ in Android
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 <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();
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...
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)
.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
.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.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.