Цель C, вызывающая методы Java с использованием JNI - PullRequest
3 голосов
/ 02 марта 2012

Может кто-нибудь показать мне, как вызывать Java-метод из Objective C.

Более подробно это на самом деле то, что я хотел бы сделать

1) Первый звонок со стороны java к цели C. Во время этого звонка я хотел бы получить ссылку на объект java.

2) Позже я бы хотел, чтобы Objective C использовала ссылку, полученную на предыдущем шаге, для вызова методов Java.

Спасибо

1 Ответ

5 голосов
/ 07 марта 2012

Следующее похоже на работу.Это основано на вышеупомянутом комментарии на следующих примерах C и этой ссылке.

http://urlgrey.net/?p=121

Как говорит ссылка, не создавайте глобальную переменную для env, вместо этого создайте глобальную переменную jvm, а также создайте глобальную ссылку на ваш класс.

Вот как я реализую шаг 1: «1) Первый вызов со стороны java к цели C. Во время этого вызова я хотел бы получить ссылку на объект java.»

Сначала объявите глобальную переменную в заголовочном файле для

1) jvm:

JavaVM *jvm;

2) Класс Java:

jclass smartCallbackClass;

3) JavaОбъект:

jobject smartCallbackObject;

Далее в вызове, который поступает со стороны Java на Objective C, установите значения для этих переменных

1) Для JVM:

(*env)->GetJavaVM(env, &jvm);

2) Для объекта:

smartCallbackObject = (*env)->NewGlobalRef(env, obj);

3) Для класса:

if (smartCallbackClass == NULL) {
    jclass localRefCls = (*env)->FindClass(env,"com/studyisland/nativelibs/smart/responsesdk/interfaces/thin/SMARTResponseThinClient"); 
    if (localRefCls == NULL) {
        NSLog(@"Unable to create a JNI Java Class reference \n");
    }
    //Create a global reference for JNI Java class
    smartCallbackClass = (*env)->NewGlobalRef(env,localRefCls);

    //Delete the local reference as it is no longer needed
    (*env)->DeleteLocalRef(env, localRefCls);

    //Is the global reference created successfully?
    if (smartCallbackClass == NULL) {
        NSLog(@"Unable to create JNI Java class reference \n");
        return 0;
    }       
}

Вот ссылка, откуда я получил код для класса

http://java.sun.com/docs/books/jni/html/refs.html

Теперь второй шаг

"2) Позже я хотел бы, чтобы Objective C использовал ссылку, полученную на предыдущем шаге, для вызова методов Java"

Для вызова из Objective C обратно в Java вам необходимо убедиться, что вызов выполняется в том же потоке, которым Java назвала Objective C, поэтому вот код.

-(void)classFailedToStop:(SMARTResponseCallBackEventArg*)anArg{
    JNIEnv *env;
    int attach = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
    if(attach == 0){
        (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4);
        jmethodID method = (*env)->GetMethodID(env, smartCallbackClass, "callback_onStopClassFailed", "()V");
        (*env)->CallVoidMethod(env, smartCallbackObject, method);
    }
    (*jvm)->DetachCurrentThread(jvm);

}

Надеюсь, это поможет.

...