各位好:
小弟目前必須使用JNI的invocation API去cearteVM再找到特定的object並呼叫其方法,
, 呼叫物件方法如果由java call C的時候是很容易實作的因為與JVM的通道是由java打開 , 但是如果今天倒過來要由C呼叫java中的物件(與JVM的通道是由C打開)這樣的話就不是很清楚該怎麼做 , 因為C的部分是在linux下執行所以有想過應該是要create一個thread讓他可以使用invocation API指回JVM 再去找java物件 , 因為小弟我不熟linux的東西 , 不曉得各位是否可以推薦相關的網站或是資料可以給小弟參考 , 或是知道這種issue應該要由怎樣的方向下手會比較好 , 請給小弟一些建議
thanks a lot
4 則回應
請參考這裡解答
http://www.android1.net/Topic.aspx?BoardID=11&TopicID=1199
果然站上隱藏著強者啊!!!!!!
#include <stdio.h>
#include <jni.h>
#include <string.h>
JNIEnv* create_vm(JavaVM ** jvm)
{
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[2];
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path=."; /* user classes */
vm_args.version = JNI_VERSION_1_4; //JDK version.
vm_args.options = options;
vm_args.nOptions = 2;
vm_args.ignoreUnrecognized = 0;
int ret = JNI_CreateJavaVM(jvm, &env, &vm_args);
if(ret < 0)
printf("\nUnable to Launch JVM %d\n",ret);
return env;
}
int main(int argc, char* argv[])
{
JNIEnv *env;
JavaVM * jvm;
env = create_vm(&jvm);
if (env == NULL)
return 1;
jclass clsH =NULL;
jmethodID midMain = NULL;
jmethodID midCalling = NULL;
clsH = env->FindClass("Hello");
if (clsH != NULL)
{
midMain = env->GetStaticMethodID(clsH, "main", "([Ljava/lang/String;)V");
midCalling = env->GetStaticMethodID(clsH,"TestCallMethod","(Ljava/lang/String;)V");
}
else
{
printf("\nUnable to find the requested class\n");
}
/************************************************************************/
/* Now we will call the functions using the their method IDs */
/************************************************************************/
if(midMain != NULL)
env->CallStaticVoidMethod(clsH, midMain, NULL); //Calling the main method.
if (midCalling!=NULL)
{
jstring StringArg = env->NewStringUTF("\nTestCall:Called from the C Program\n");
//Calling another static method and passing string type parameter
env->CallStaticVoidMethod(clsH,midCalling,StringArg);
}
//Release resources.
int n = jvm->DestroyJavaVM();
return 0;
}
非常感謝這位好心的同好的回應:
你所提出的解答是屬於C要呼叫一般的java的做法 , 在android平台上不太一樣 , 在android上可以直接經由JNI_OnLoad(JavaVM *vm,void *reserved)直接取得指向android dalvik vm的ponter , 但現在我的問題是卡在 , 我將該pointer存在一個static global JavaVM* , 讓其他的thread可以使用 , 在一般的C呼叫java可行但是在android卻不行 , 找過很多相關的資料也都是相同的做法當然都不是android平台就是 , 換句話說android平台在invocation API這部分似乎和一般的JNI寫法應該有不同的地方 , 畢竟android的VM是自家做的跟一般的java VM有不同 , 不曉得有沒有人知道這個問題怎解 , 或是大家有不同的想法可以提出來討論一下
感謝