如何创buildAndroid代码和本机代码之间的callback?

我有一个要求在本地代码(C语言代码)和Android代码之间创buildcallback。 我写了JNI函数从这样的android调用C code

JNI代码在这里

 #include <android/log.h> void initSocket(); #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_org_pjsip_pjsua_pjsua_1appJNI_initSocket(JNIEnv *jenv, jclass jcls) { __android_log_write(ANDROID_LOG_INFO, " JNI CODE ", " APP INIT SOCKET"); initSocket(); } } 

C代码看起来像这样

 void initSocket() { /// some more stuff printf(" initSocket function "); } static int worker_thread(void *unused) { /// some more stuff return 0; } pj_bool_t on_rx_data1(pj_stun_sock *stun_sock, void *pkt, unsigned pkt_len, const pj_sockaddr_t *src_addr, unsigned addr_len) { /// some more stuff return PJ_TRUE; } pj_bool_t on_data_sent1 (pj_stun_sock *stun_sock, pj_ioqueue_op_key_t *send_key, pj_ssize_t sent) { /// some more stuff return PJ_TRUE; } pj_bool_t on_status1(pj_stun_sock *stun_sock, pj_stun_sock_op op, pj_status_t status) { /// some more stuff returnsockaddress(); return PJ_TRUE; } char* returnsockaddress() { /// some more stuff return ipinttostring(sock_address); } char* ipinttostring(unsigned int addr ) { /// some more stuff return fullIP; } 

这是我在C语言中使用的代码,从JNI调用initSocket()函数。 现在我想在此代码中调用on_status1函数时on_status1 C code创build一个callback 。 这个on_status1将在几秒钟内重复,当它被称为我想在android代码中调用一个函数。

编辑

我试过这样,但没有成功

 JNIEXPORT void JNICALL Java_org_pjsip_pjsua_pjsua_1appJNI_initSocket(JNIEnv *jenv, jobject obj) { __android_log_write(ANDROID_LOG_INFO, " JNI CODE ", " APP INIT SOCKET"); initSocket(); jclass cls = jenv->GetObjectClass(obj); jmethodID methodid = env->GetMethodID(cls, "callback", "()V"); if(!methodid) { return; } jenv->CallVoidMethod(obj , methodid); } 

我在android代码中被声明为这样的函数。

 public static void callback(String value) { Log.e(TAG, "value:" + value); } 

Solutions Collecting From Web of "如何创buildAndroid代码和本机代码之间的callback?"

尝试这个 :

 JNIEXPORT void JNICALL Java_org_pjsip_pjsua_pjsua_1appJNI_initSocket(JNIEnv *jenv, jobject obj) { __android_log_write(ANDROID_LOG_INFO, " JNI CODE ", " APP INIT SOCKET"); initSocket(); // jclass cls = (*jenv)->GetObjectClass(jenv, obj); // or something like this : jclass cls = (*jenv)->FindClass(jenv, "org/pjsip/pjsua/pjsua_appJNI"); jmethodID methodid = (*jenv)->GetStaticMethodID(jenv, cls, "callback", "(Ljava/lang/String;)V"); if(!methodid) { return; } jstring jstr = (*jenv)->NewStringUTF(jenv, "Hello from C"); (*jenv)->CallStaticVoidMethod(jenv, cls, methodid, jstr); } 

从java代码:

 public static void callback(String value){ Log.e(TAG, "value:"+value); } 

并在C:

 typedef struct JniSMSMethodInfo { JNIEnv * env; jclass classID; jmethodID methodID; } JniMethodInfo; extern "C" { static JNIEnv* getJNIEnv(void) { JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { LOGD("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL"); return NULL; } JNIEnv *env = NULL; // get jni environment jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); switch (ret) { case JNI_OK : // Success! return env; case JNI_EDETACHED : // Thread not attached // TODO : If calling AttachCurrentThread() on a native thread // must call DetachCurrentThread() in future. // see: http://developer.android.com/guide/practices/design/jni.html if (jvm->AttachCurrentThread(&env, NULL) < 0) { LOGD("Failed to get the environment using AttachCurrentThread()"); return NULL; } else { // Success : Attached and obtained JNIEnv! return env; } case JNI_EVERSION : // Cannot recover from this error LOGD("JNI interface version 1.4 not supported"); default : LOGD("Failed to get the environment using GetEnv()"); return NULL; } } // get class and make it a global reference, release it at endJni(). static jclass getClassID(JNIEnv *pEnv) { jclass ret = pEnv->FindClass(CLASS_NAME); if (! ret) { LOGD("Failed to find class of %s", CLASS_NAME); } return ret; } static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *methodName, const char *paramCode) { jmethodID methodID = 0; JNIEnv *pEnv = 0; bool bRet = false; do { pEnv = getJNIEnv(); if (! pEnv) { break; } jclass classID = getClassID(pEnv); methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode); if (! methodID) { LOGD("Failed to find static method id of %s", methodName); break; } methodinfo.classID = classID; methodinfo.env = pEnv; methodinfo.methodID = methodID; bRet = true; } while (0); return bRet; } void callback(char* value){ JniMethodInfo methodInfo; if (! getStaticMethodInfo(methodInfo, "callback", METHOD_SIGNATURE)) { return; } jstring stringArg = methodInfo.env->NewStringUTF(value); methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg1); methodInfo.env->DeleteLocalRef(stringArg); methodInfo.env->DeleteLocalRef(methodInfo.classID); } } 

CLASS_NAME:/ METHOD_SIGNATURE:从文件* .class中查看