网站设计的市场分析,自己做网站导航,做任务的网站有那些,做计划的网站本文将带你了解Android应用开发Android JNI-c/c调用java方法#xff0c;希望本文对大家学Android有所帮助。Android JNI-c/c调用java方法#xff0c;在使用ndk开发的时候#xff0c;java调用c/c方法是必须要的。但是很多时候#xff0c;c/c有callback需要反馈给jav…本文将带你了解Android应用开发Android JNI-c/c调用java方法希望本文对大家学Android有所帮助。Android JNI-c/c调用java方法在使用ndk开发的时候java调用c/c方法是必须要的。但是很多时候c/c有callback需要反馈给java的时候(比如IM通讯登录成功信息和一些异常信息)就需要c/c调用java方法了。在看这篇文章之前必须对JNI有一些基础的了解比如java调用c/c方法java和c/c jni在一些基本类型上的对应(int对应jint等)。那么现在介绍一下c/c调用java方法的基本步骤1.需要把java方法所在类的实例通过JNI方法传到c/cjava:JNI, 这是c需要回调的java方法然后通过调用自身init()方法把java实例传到c层?123456class JNI {public native void init(JNI obj);public void error(int code) {Log.i(JNI, c call error );}}c:这里把java传递进来的objListener保存到c的jniobj结构体内。?123456789101112131415161718192021222324JNIEXPORT jint JNICALL Java_com_arcvideo_rtcmessage_JNI_init(JNIEnv *env,jobject oj,jobject objListener,){if(objListener MNull){MVLOG(objListener is null);}else{MVLOG(get java obj);jniobj-g_obj env-NewGlobalRef(objListener);}return res;}typedef struct _tagJNIObj{//这个是刚才保存java实例的结构体在还有其他参数jmethodID JNI_error;JavaVM* g_jvm;JNIEnv* g_ThreadEnv;jclass g_class;jobject g_obj;MHandle g_h;}JNIObj;static JNIObj* jniobj MNull;2.在c层拿到java classc:通过jni提供的FindClass方法和完整类名可以拿到class引用?12static const char* const DL_CLASS_NAME com/arcvideo/rtcmessage/JNI;jniobj-g_class env-FindClass(DL_CLASS_NAME);3.在c层拿到java methodc:根据刚才拿到的java class引用有jni提供的GetMethodID方法和方法名入参就可以拿到method引用?123456// errorjniobj-JNI_error env-GetMethodID(jniobj-g_class, error,(I)V);if(jniobj-JNI_error MNull){MVLOG(create JNI_error is error);}4.调用methodc:在需要调用的地方调用这个java方法?1234567891011121314151617181920212223242526static void error(MDWord code, MVoid* pObj){MVLOG(RtcMessageJNI error is in code : %d, code );if(jniobj-g_ThreadEnv MNull){MVLOG(attach current thread start);jniobj-g_jvm - AttachCurrentThread(jniobj-g_ThreadEnv, MNull);if(jniobj-g_ThreadEnv MNull){MVLOG(attach current thread is error);return;}}if(jniobj jniobj-JNI_error){MVLOG(RtcMessageJNI error is called);//这里是最关键的调用过程通过JNI提供的CallVoidMethod来调用加入参数class引用method应用已经入参这样调用java方法就完成了。jniobj-g_ThreadEnv-CallVoidMethod(jniobj-g_obj, jniobj-JNI_error,(int)code);}if(jniobj-g_jvm){MVLOG(RtcMessageJNI error method detach);jniobj-g_jvm-DetachCurrentThread();jniobj-g_ThreadEnv MNull;}}这里在调用java方法的时候调用了AttachCurrentThread和DetachCurrentThread方法这是必须的如果不调用AttachCurrentThread就拿不到线程的引用会报错误。然后在调用结束的时候要调用DetachCurrentThread也就是释放线程。根据个人经验最好每次调用java方法结束的时候都调用DetachCurrentThread这样基本不会出错。本文由职坐标整理并发布希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道