深入浅析jni中的java接口使用
JNI中的java接口使用
项目需求,需要在c++函数中监听相应的状态,并在java端进行一些列的处理。
这个需要在JNI中写一个subscriber,注册后在需要的地方进行引入使用。
目录结构
初始化是AS上的c++工程文件,这边先暂时实现简单的demo,CdemoActivity是NativeActivity的实现,我们暂时别管,因为实现是c++层控制的,有兴趣可以去百度下
主要涉及jnicallback等c文件和JNIUtil这java文件
JNIUtil
publicclassJNIUtil{ static{ System.loadLibrary("native-event"); } //注册函数 publicstaticnativevoidsetJniCallBack(JniCallBackcallBack); //解注册函数 publicstaticnativevoidunJniCallBack(); publicinterfaceJniCallBack{ voidonReceiveCInfo(); } }
jnicallback.h
// //Createdby86130on2020/9/9. // #ifndefCDEMO_JNICALLBACK_H #defineCDEMO_JNICALLBACK_H #ifdef__cplusplus extern"C"{ #endif //方法回调 voidonReceiveMsg(); #ifdef__cplusplus } #endif #endif//CDEMO_JNICALLBACK_H
jnicallback.cpp
#include#include #include #include"jnicallback.h" #ifdef__cplusplus extern"C"{ #endif JavaVM*g_VM; jobjectsubscriber; extern"C" JNIEXPORTvoidJNICALLJava_com_demo_cdemo_JNIUtil_setJniCallBack(JNIEnv*env,jclassclazz,jobjectcall_back){ env->GetJavaVM(&g_VM); subscriber=env->NewGlobalRef(call_back); } extern"C" JNIEXPORTvoidJNICALLJava_com_demo_cdemo_JNIUtil_unJniCallBack(JNIEnv*env,jclassclazz){ if(subscriber!=NULL) { env->DeleteGlobalRef(subscriber); } } JNIEnv*getEnv() { JNIEnv*env; if(g_VM==NULL) { returnNULL; } intenvStat=g_VM->GetEnv((void**)&env,JNI_VERSION_1_6); if(envStat==JNI_EDETACHED) { if(g_VM->AttachCurrentThread(&env,NULL)!=0) { returnNULL; } } returnenv; } jmethodIDgetMethodIdByNameAndSig(JNIEnv*env,constchar*name,constchar*sig) { if(env==NULL||subscriber==NULL) { returnNULL; } jclasssubscriberClass=env->GetObjectClass(subscriber); if(subscriber==0) { returnNULL; } jmethodIDmethodId=env->GetMethodID(subscriberClass,name,sig); if(methodId==0) { returnNULL; } returnmethodId; } //头文件方法实现 voidonReceiveMsg() { JNIEnv*env=getEnv(); jmethodIDonReceiveMethodId=getMethodIdByNameAndSig(env,"onReceiveCInfo","()V"); if(onReceiveMethodId==NULL) { return; } env->CallVoidMethod(subscriber,onReceiveMethodId); } #ifdef__cplusplus } #endif
在其他的cpp文件中引入jnicallback的头文件就可以使用相应的方法。
CMake文件
project(Native-Activity) cmake_minimum_required(VERSION3.4.1) #引入native_app_glue头文件 include_directories(F:/AndroidSdk/Sdk/ndk-bundle/sources/android/native_app_glue) add_library(native-activitySHARED main.cpp jnicallback.cpp) add_library(native-eventSHAREDjnicallback.cpp) find_library(log-liblog) find_library(OPENGLES3_LIBRARYGLESv3"OpenGLESv3.0library") find_library(EGL_LIBRARYEGL"EGL1.4library") find_library(android-libandroid) #编译为静态库 add_library(app_glueSTATIC android_native_app_glue.c) target_link_libraries(native-event ${log-lib}#链接log库 ${android-lib}#链接android库 ) target_link_libraries(native-activity app_glue#链接静态库native_app_glue ${log-lib}#链接log库 ${android-lib}#链接android库 ${OPENGLES3_LIBRARY}#链接OpenGLES库 ${EGL_LIBRARY}#链接EGL库 )
JNIUtil的使用
packagecom.demo.cdemo; importandroid.app.NativeActivity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.os.Looper; importandroid.util.Log; publicclassCdemoActivityextendsNativeActivity{ static{ System.loadLibrary("native-activity"); } booleanisFirst=false; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); JNIUtil.setJniCallBack(newJNIUtil.JniCallBack(){ @Override publicvoidonReceiveCInfo(){ booleanisMain=isMainThread(); Log.d("zzkk", "CdemoActivityonReceiveCInfoisMain="+isMain); if(!isFirst) { isFirst=true; runOnUiThread(newRunnable(){ @Overridepublicvoidrun(){ Intentintent=newIntent(CdemoActivity.this ,MainActivity.class); startActivity(intent); } }); } } }); } privatebooleanisMainThread(){ returnLooper.getMainLooper()==Looper.myLooper(); } }
可以看见onReceiveCInfo这行日志的打印
综上
到此这篇关于jni中的java接口使用的文章就介绍到这了,更多相关java接口使用内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。