2013-12-13 6 views
0

У меня есть код JNI, и я пытаюсь вызвать статический метод в Java.Android: CallStaticVoidMethod вызывается только один раз

OnLoad в JNI выглядит, как показано ниже

extern "C" jint JNI_OnLoad(JavaVM *jvm, void *reserved) { 
     JNIEnv *e; 

     mJvm = jvm; 

     if (jvm->GetEnv((void**) &e, JNI_VERSION_1_4) != JNI_OK) { 
       ALOGE("Error getting Env var"); 
       return JNI_ERR; 
     } 

     ALOG_ASSERT(env, "Could not retrieve the env!"); 

     app = e->FindClass("xyz"); 
     updateService = e->GetStaticMethodID(app, "updatestatus", "(I)V"); 

     jniRegisterNativeMethods(e, "xyz", 
           Methods, NELEM(Methods)); 

     return JNI_VERSION_1_4; 
} 

Я следующие глобальные переменные

JavaVM *mJvm; 
jclass app; 
jmethodID updateHDToService; 

Обратный вызов, где я пытаюсь вызвать метод Java выглядит следующим образом

JNIEnv *e; 
if (!mIsListenerAttached) { 
     if (mJvm->AttachCurrentThread(&e, NULL) != JNI_OK) { 
       ALOGE("Error attaching native thread to java"); 
       mIsListenerAttached = false; 
       return; 
     } 
     ALOGI("Aattached native thread to java"); 
     mIsListenerAttached = true; 
} 

e->CallStaticVoidMethod(app, updateHDToService, radioContext->signalStat); 

Статический метод в Java называется успешно только один раз. В следующий раз, когда выполняется тот же обратный вызов, он не вызывает метод java.

Что я делаю wronG?

+0

Существует, очевидно, некоторый класс, который имеет член 'bool mIsListenerAttached'. Ваш код ожидает, что будет один экземпляр этого элемента на (собственный) поток. Но если вы намереваетесь вызывать 'xyz.uodatestatus()' Java void method больше, чем из одного собственного потока, вам, вероятно, нужно сохранить 'mIsListenerAttached' в локальном хранилище потоков (иначе TLS) или использовать альтернативный механизм. _ И не забудьте называть 'mJvm-> detachCurrentThread()' до того, как исходный поток будет удален._ –

+0

@AlexCohn У меня есть 'bool mIsListenerAttached' как глобальная переменная в моем файле JNI. У меня нет класса в моем JNI. Это само по себе может быть проблемой, а не уверенностью. Я новичок в JNI. Как узнать, есть ли несколько родных потоков? – vishalm

ответ

0

Пожалуйста, взгляните на http://developer.android.com/training/articles/perf-jni.html. Вам не нужна переменная защиты, Calling AttachCurrentThread on an already-attached thread is a no-op..

Но не забудьте позвонить mJvm->detachCurrentThread() перед тем, как родной поток выйдет!

+0

Как узнать, когда выйдет собственный поток? – vishalm

+0

Когда поток [создан] (http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_create), он запускает так называемую «функцию потока». В конце концов, он либо называет [ptherad_exit()] (http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_exit), либо просто возвращает. Это конец срока службы резьбы. Если нить была прикреплена к JVM, она должна быть явно отключена до того, как она закончится в любом из указанных способов. Фактически вы можете отключить поток сразу после вызова обратного вызова Java, но если это происходит слишком часто, накладные расходы могут быть значительными. –

+0

Еще один немой вопрос. Я не начинаю нить явно. Я создаю библиотеку JNI и загружаю эту библиотеку в код приложения Java. – vishalm

Смежные вопросы