加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Android NDK 线程回调Java层技巧

发布时间:2021-11-19 16:27:59 所属栏目:教程 来源:互联网
导读:项目上刚好要在Android NDK层使用线程回调Java层方法,仅以此文做个总结。线程使用pthread创建(在此略过),线程会循环调用NofityDataCB函数: static JavaVM* s_jVM = NULL; static jobject s_jobj = NULL; //java object static jmethodID s_jcallback =

项目上刚好要在Android NDK层使用线程回调Java层方法,仅以此文做个总结。线程使用pthread创建(在此略过),线程会循环调用NofityDataCB函数:
 
static JavaVM* s_jVM = NULL;
static jobject s_jobj = NULL; //java object
static jmethodID s_jcallback = NULL; //方法id
 
static void NotifyDataCB(unsigned char flag, int x, int y, int w, int h, unsigned char* buff, mp_i64 timeStamp)
{
 //LOG_DBG("[NotifyDataCB()] enter.");
 JNIEnv* env;
 
 s_jVM->AttachCurrentThread(&env, NULL); //获取当前线程的JNIEnv*
 
 env->CallVoidMethod(s_jobj, s_jcallback, ...); //调用java层相关方法
 
 s_jVM->DetachCurrentThread(); //释放当前线程的JNIEnv*
 
 //LOG_DBG("[NotifyDataCB()] done.");
 return;
}
 
此处的重点即为:
 
jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);
 
Attaches the current thread to a Java VM. Returns a JNI interface pointer in the JNIEnv argument.
 
其中s_jVM是由JNI_OnLoad方法保存而来的;
 
s_jobj在自定义的jni方法里赋值,并创建了个全局引用,使其不被虚拟机释放
 
s_jobj = env->NewGlobalRef(thiz); //thiz为jni方法的参数,表示java层的类对象
 
该s_jobj需要手动释放:
 
env->DeleteGlobalRef(s_jobj);
 
s_jcallback也是在自定义的jni方法调用以下方法保存而来:
 
static jmethodID GetClassMethodID(JNIEnv* env)
{
 jclass clazz = env->FindClass(classPathName); //classPathName完整的包名加类名
 if (clazz == NULL)
 {
  LOG_ERR("[GetClassMethod()]Failed to find jclass");
  return NULL;
 }
 
 
 jmethodID jcallback = env->GetMethodID(clazz, "OnNativeDataCB", "(BIIII[IJ)V"); //获取java层方法id
 if (jcallback == NULL)
 {
  LOG_ERR("[GetClassMethod()]Failed to find method OnNativeDataCB");
  return NULL;
 }
 
 return jcallback; //返回保存为s_jcallback
}
 
综上所述,关键步骤为:
1. 在onload的时候保存JavaVM指针。
2. 在自定义jni方法里(该方法须在callback方法使用前调用,例如初始化方法)保存callback方法所在对象,且该对象需要创建一个全局引用以便在线程方法里使用,默认是local ref,函数执行完会被虚拟机释放;另外自定义jni方法和callback方法在同一个类里,所以在调用自定义方法时能保存一致的jobject  。
3. 也是在自定义jni方法中,通过class获得该callback的method ID。

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读