2022-09-28 Android APP 用interface 接口的形式对jni进行回调,实例测试

 一、看到别人的代码里面用 interface 接口的形式跟jni进行回调,做数据交互,然后就想搞给例子测试一下。

 二、学习最好的方法,就是read the fuck code,有兴趣自己download源码下来分析吧。

(657条消息) AndroidAPP用interface接口的形式对jni进行回调,实例测试-OS文档类资源-CSDN文库icon-default.png?t=M85Bhttps://download.csdn.net/download/qq_37858386/86725721

三、实例测试

       1、源码概览

        2、随便看jni 源码

#include<stdlib.h>
#include<pthread.h>
#include<jni.h>
#include<android/log.h>
#include "com_example_jnicallbackdemo_Callbacktest.h"

#define LOG_TAG "JNICALLBACK"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

jmethodID mid;
jclass objclass;
jobject mobj;
pthread_t thread;
JavaVM *m_vm;

jmethodID javaCallbackId ;
jobject callback;

//初始化的时候会调进来一次,在这个方法里持有jvm的引用
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved){
    m_vm=vm;
    JNIEnv* env = NULL;
    jint result = -1;
    if(m_vm){
        LOGD("m_vm init success");
    }else{
        LOGD("m_vm init failed");
    }
    if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK){
        return result;
    }
    return JNI_VERSION_1_4;
}
JNIEnv* getJNIEnv(int* needsDetach){
    JNIEnv* env = NULL;
    jint result = -1;
    if ((*m_vm)->GetEnv(m_vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK){
        int status = (*m_vm)->AttachCurrentThread(m_vm, &env, 0);
        if (status < 0){
            LOGD("failed to attach current thread");
            return NULL;
        }
        *needsDetach = 1;
    }
    LOGD("GetEnv Success");
    return env;
}

void *thread_run(){
    LOGD("thread start");
    LOGD("start noop callback");
    int number = 0 ;
    int needsDetach;
    JNIEnv *evn=getJNIEnv(&needsDetach);
    while(1)
    {
         usleep(1000*1000);
         (*evn)->CallVoidMethod(evn, callback, javaCallbackId,number);
         number = number+1;
     }
}

JNIEXPORT void JNICALL Java_com_example_jnicallbackdemo_Callbacktest_native_1say_1hello(JNIEnv *evn, jobject object,jobject greet_listener){
      LOGD("JNIDEMO  Java_com_example_jnicallbackdemo_MainActivity_native_say_hello  greet_listener ");
      if(!greet_listener)
        return;

      callback = (*evn)->NewGlobalRef(evn, greet_listener);

      jclass javaClass = (*evn)->GetObjectClass(evn, callback);
      if (javaClass == 0) {
             LOGD (" JNIDEMO Unable to find class");
             return;
       }
     javaCallbackId = (*evn)->GetMethodID(evn, javaClass,
                                              "recvWiegandMsg", "(I)V");
     if (javaCallbackId == NULL) {
        LOGD("JNIDEMO Unable to find method:onProgressCallBack");
        return;
    }
    (*evn)->CallVoidMethod(evn, callback, javaCallbackId,18);
    pthread_create(&thread, NULL, thread_run, NULL);
}

        3、用ndk编译jni 成so, 直接到jni源码目录下执行ndk-build命令就可以。

        4、直接看测试效果,查看打印的log

         5、


四、有价值的参考文章

Android JNI 篇 - JNI回调的三种方法(精华篇) - 简书 (jianshu.com)icon-default.png?t=M85Bhttps://www.jianshu.com/p/e576c7e1c403
(658条消息) JNI 接口回调_pang_gua的博客-CSDN博客_jni 回调icon-default.png?t=M85Bhttps://blog.csdn.net/pang_gua/article/details/86634327

猜你喜欢

转载自blog.csdn.net/qq_37858386/article/details/127091581