一、看到别人的代码里面用 interface 接口的形式跟jni进行回调,做数据交互,然后就想搞给例子测试一下。
二、学习最好的方法,就是read the fuck code,有兴趣自己download源码下来分析吧。
三、实例测试
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)https://www.jianshu.com/p/e576c7e1c403
(658条消息) JNI 接口回调_pang_gua的博客-CSDN博客_jni 回调https://blog.csdn.net/pang_gua/article/details/86634327