一、看到别人的代码里面用 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