How to create callbacks between android code and native code?

前端 未结 2 340
醉梦人生
醉梦人生 2020-12-29 14:39

I have a requirement for creating call backs between native code ( c language code) and Android code . I wrote JNI functions for calling C code from the androi

相关标签:
2条回答
  • 2020-12-29 14:48

    Try this :

    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); 
      }
    
    0 讨论(0)
  • 2020-12-29 15:04

    From java code:

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

    And call in 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: see it from file *.class

    0 讨论(0)
提交回复
热议问题