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 asenv->FindClass(someString), not how you’re doing it. If it was C you’d useFindClass(env, someString)but in C++ you useenv->FindClass(someString).FindClassis the fully qualified path name but with/as the delimiter instead of.For example, if the class isFooin packagebar.baz.quux, the fully-qualified name isbar.baz.quux.Fooand the string you’d give toFindClassisbar/baz/quux/Foo.JavaVM* vmbe 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 calledJNI_CreateJavaVM()will use theJNIEnv *that gets filled in by that call. Every other thread that wants to use the JVM needs to callAttachCurrentThreadwhich will bind that thread to the JVM and fill in a newJNIEnv *valid for that thread.JDK_HOME/includedirectory (which containsjni.h) is in the includes search path? Same for theJDK_HOME/include/androiddirectory (or whatever the operating specific directory inJDK_HOME/includeis 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.