Android ndk 线程回调java层方法
2014-04-29 17:09
239 查看
项目上刚好要在ndk层使用线程回调java层方法,仅以此文做个总结。
线程使用pthread创建(在此略过),线程会循环调用NofityDataCB函数:
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需要手动释放:
s_jcallback也是在自定义的jni方法调用以下方法保存而来:
综上所述,关键步骤为:
1. 在onload的时候保存JavaVM指针。
2. 在自定义jni方法里(该方法须在callback方法使用前调用,例如初始化方法)保存callback方法所在对象,
且该对象需要创建一个全局引用以便在线程方法里使用,默认是local ref,函数执行完会被虚拟机释放;
另外自定义jni方法和callback方法在同一个类里,所以在调用自定义方法时能保存一致的jobject 。
3. 也是在自定义jni方法中,通过class获得该callback的method ID。
线程使用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。
相关文章推荐
- Android NDK 线程回调Java层方法
- Android NDK 工具链的使用方法(Standalone Toolchain)
- android ndk程序调试方法
- 【学习Android NDK开发】native code通过JNI调用Java方法
- android ndk常见的问题及解决的方法
- Android ndk 编译问题解决方法
- 消除“Android NDK: WARNING: APP_PLATFORM”的方法
- android NDK安装与配置过程问题与解决方法。坑爹啊!
- 【学习Android NDK开发】native code通过JNI调用Java方法
- Android NDK 工具链的使用方法(Standalone Toolchain)
- Android ndk获取手机内部存储卡的根目录方法
- Android NDK编程浅入深出之--域和方法的操作
- Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)
- Android NDK 工具链的使用方法(Standalone Toolchain)
- Android NDK 工具链的使用方法(Standalone Toolchain)
- 文件方法Android NDK开发的环境配置和使用
- 基于 Android NDK 的学习之旅----- Java 方法映射到C中的签名(附源码)
- 【学习Android NDK开发】native code通过JNI调用Java方法
- android NDK和源码中输出Log信息的方法
- 两种方法将Android NDK samples中hello-neon改成C++