JVM_NATIVE
来源:互联网 发布:爱淘宝天猫购物券 编辑:程序博客网 时间:2024/06/09 23:16
jvm 调用native方法,供java访问本地方法。需要java层提供本地方法声明,在通过jvm中运行的jni运行环境对相应的本地声明方法进行注册,以达到native方法和java交互。
example:
#include "JNIHelp.h"#include "jni.h"#include "init.h"#include "callback_interface.h"#define LOG_NDEBUG 0#endif#include "utils/Log.h"#include "android_runtime/AndroidRuntime.h"#include <string.h>#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include "can_protocol.h"namespace android{ static jobject gObject = NULL; static JNIEnv *sCallbackEnv = NULL; static JavaVM *g_jvm = NULL; // static jmethodID method_temperature_change_callback; static jmethodID method_wind_force_change_callback; static jmethodID method_wind_direction_change_callback; static jmethodID method_anion_change_callback; static jmethodID method_aqs_change_callback; static jmethodID method_clear_fog_prev_change_callback; static jmethodID method_clear_fog_suf_change_callback; static jmethodID method_inner_loop_change_callback; static jmethodID method_auto_mode_change_callback; static jmethodID method_ac_change_callback; static jmethodID method_ac_max_change_callback; static jmethodID method_dual_change_callback; static jmethodID method_pm25_change_callback; static jmethodID method_fan_change_callback; static Init init; static CallBack cbs;#define SERVICE_CLASS_NAME ("com/android/server/air/AirService") // static bool checkCallbackThread(){ JNIEnv * env = AndroidRuntime::getJNIEnv(); if(env == NULL || env != sCallbackEnv){ ALOGE("Callback env check fail: env: %p, callback: %p",env,sCallbackEnv); return false; } return true; } // void checkAndClearExceptionFromCallback(JNIEnv * env,const char* methodName){ if(env->ExceptionCheck()){ ALOGE("An exception was thrown by callback '%s'.",methodName); //LOGE_EX(env); env->ExceptionClear(); } } // static void temperature_change_callback(int32_t temperature,int32_t type){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("temperature = %d type=%d \n",temperature,type); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_temperature_change_callback,(jint)temperature,(jint)type); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void wind_force_change_callback(int32_t windForce){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("wind_force = %d \n",windForce); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_wind_force_change_callback,(jint)windForce); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void wind_direction_change_callback(int32_t windDirection){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("wind_direction = %d \n",windDirection); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_wind_direction_change_callback,(jint)windDirection); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void anion_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("anion = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_anion_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void aqs_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("aqs = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_aqs_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void clear_fog_prev_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("clear_fog_prev = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_clear_fog_prev_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void clear_fog_suf_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("clear_fog_suf = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_clear_fog_suf_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void inner_loop_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("inner_loop = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_inner_loop_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void auto_mode_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("auto_mode = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_auto_mode_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void ac_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("ac = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_ac_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void ac_max_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("ac_max = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_ac_max_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void dual_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("dual = %d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_dual_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void pm25_change_callback(int pm_val,int type){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("pm25 = %d type=%d \n",pm_val,type); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_pm25_change_callback,(jint)pm_val,(jint)type); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } static void fan_change_callback(bool isOn){ if(g_jvm != NULL && gObject != NULL){ JNIEnv *pEnv = NULL; ALOGV("fan = %d type=%d \n",isOn); g_jvm->AttachCurrentThread(&pEnv,NULL); jclass clazz = pEnv->GetObjectClass(gObject); (pEnv)->CallVoidMethod(gObject,method_fan_change_callback,(jboolean)isOn); g_jvm->DetachCurrentThread(); }else{ ALOGE("gObject == NULL %s",__FUNCTION__); } } // static void com_aircondition_cleanup(JNIEnv *env){ } // static bool com_aircondition_initialize(JNIEnv*env,jobject object){ ALOGV("%s",__FUNCTION__); cbs.setWindForceCallback(wind_force_change_callback); cbs.setTemperatureCallback(temperature_change_callback); cbs.setWindDirectionCallback(wind_direction_change_callback); cbs.setAnionCallback(anion_change_callback); cbs.setAqsCallback(aqs_change_callback); cbs.setClearFogPrevCallback(clear_fog_prev_change_callback); cbs.setClearFogSufCallback(clear_fog_suf_change_callback); cbs.setInnerLoopCallback(inner_loop_change_callback); cbs.setAutoModeCallback(auto_mode_change_callback); cbs.setACCallback(ac_change_callback); cbs.setACMaxCallback(ac_max_change_callback); cbs.setDualCallback(dual_change_callback); cbs.setPm25Callback(pm25_change_callback); cbs.setFanCallback(fan_change_callback); init.setCallBacks(&cbs); // env->GetJavaVM(&g_jvm); gObject = env->NewGlobalRef(object); // int ret = 0; if((ret = init.start()) != 0){ ALOGE("%s Failed!\n",__FUNCTION__); return false; } ALOGV("%s success \n",__FUNCTION__); return true; } // static void com_aircondition_classInit(JNIEnv* env,jclass clazz){ ALOGV("%s",__FUNCTION__); jclass callbackClass=env->FindClass(SERVICE_CLASS_NAME); method_temperature_change_callback = env->GetMethodID(callbackClass, "temperatureChangeCallback","(II)V"); method_wind_force_change_callback = env->GetMethodID(callbackClass, "windForceChangeCallback","(I)V"); method_wind_direction_change_callback = env->GetMethodID(callbackClass, "windDirectionChangeCallback","(I)V"); method_anion_change_callback = env->GetMethodID(callbackClass, "anionChangeCallback","(Z)V"); method_aqs_change_callback = env->GetMethodID(callbackClass, "aqsChangeCallback","(Z)V"); method_clear_fog_prev_change_callback = env->GetMethodID(callbackClass, "clearFogPrevChangeCallback","(Z)V"); method_clear_fog_suf_change_callback = env->GetMethodID(callbackClass, "clearFogSufChangeCallback","(Z)V"); method_inner_loop_change_callback = env->GetMethodID(callbackClass, "innerLoopChangeCallback","(Z)V"); method_auto_mode_change_callback = env->GetMethodID(callbackClass, "autoModeChangeCallback","(Z)V"); method_ac_change_callback = env->GetMethodID(callbackClass, "acChangeCallback","(Z)V"); method_ac_max_change_callback = env->GetMethodID(callbackClass, "acMaxChangeCallback","(Z)V"); method_dual_change_callback = env->GetMethodID(callbackClass, "dualChangeCallback","(Z)V"); method_pm25_change_callback = env->GetMethodID(callbackClass, "pm25ChangeCallback","(II)V"); method_fan_change_callback = env->GetMethodID(callbackClass, "fanChangeCallback","(Z)V"); } // //设置温度 // static void setTemperature(JNIEnv* env,jobject object,jint temperature,jint type){ if(type == DeviceCan::TEMPERATURE_LEFT){ init.getDeviceCan().setTemperatureLeft(temperature); }else if(type == DeviceCan::TEMPERATURE_RIGHT){ init.getDeviceCan().setTemperatureRight(temperature); }else{ ALOGE("Unknown temperature type!\n"); } } //设置风力 static void setWindForce(JNIEnv*env,jobject object,int windForce){ init.getDeviceCan().setWindForce(windForce); } //设置风向 static void setWindDirection(JNIEnv*env,jobject object,int windDirection){ init.getDeviceCan().setWindDirection(windDirection); } // static void setClearFogPrev(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setClearFogPrev(isOn); } // static void setClearFogSuf(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setClearFogSuf(isOn); } // static void setInnerLoop(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setInnerLoop(isOn); } // static void setAutoMode(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setAutoMode(isOn); } // static void setAC(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setAC(isOn); } // static void setACMax(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setACMax(isOn); } // static void setDualMode(JNIEnv *env,jobject object,bool isOn){ init.getDeviceCan().setDual(isOn); } // static void setAnion(JNIEnv*env,jobject object,bool isOn){ init.getDeviceCan().setAnion(isOn); } // static void setAQS(JNIEnv*env,jobject object,bool isOn){ init.getDeviceCan().setAqs(isOn); } //注册 static JNINativeMethod gMethods[] = { { "setTemperatureNative","(II)V",(void*) setTemperature }, { "setWindForceNative", "(I)V",(void*)setWindForce}, { "setWindDirectionNative","(I)V",(void*)setWindDirection}, { "setClearFogPrevNative","(Z)V",(void*)setClearFogPrev}, { "setClearFogSufNative","(Z)V",(void*)setClearFogSuf}, { "setInnerLoopNative","(Z)V",(void*)setInnerLoop}, { "setAutoModeNative","(Z)V",(void*)setAutoMode}, { "setACNative","(Z)V",(void*)setAC}, { "setACMaxNative","(Z)V",(void*)setACMax}, { "setAnionNative","(Z)V",(void*)setAnion}, { "setAQSNative","(Z)V",(void*)setAQS}, { "setDualModeNative","(Z)V",(void*)setDualMode}, { "cleanUpNative","()V", (void*) com_aircondition_cleanup }, { "initializeNative","()V", (void*) com_aircondition_initialize }, { "classInitNative","()V", (void*) com_aircondition_classInit } }; // int register_com_aircondition(JNIEnv *env){ return jniRegisterNativeMethods(env, SERVICE_CLASS_NAME, gMethods,NELEM(gMethods)); }}jint JNI_OnLoad(JavaVM * jvm,void *reserved){ JNIEnv *env=NULL; int status=0; ALOGD(" JNI loaded!"); if(jvm->GetEnv((void**)&env,JNI_VERSION_1_6)){ ALOGE("Error,JNI Version miss match!"); return JNI_ERR; } if((status = android::register_com_aircondition(env)) < 0){ return JNI_ERR; } // android::sCallbackEnv = env; return JNI_VERSION_1_6; }
在System.loadLibrary函数时,该函数会找到对应的动态库,调用JNI_OnLoad函数,
下面定义了函数指针
#ifndef com_aircondition_callback_interface_h#define com_aircondition_callback_interface_htypedef void (*TEMPERATURE_CB)(int temperature,int type);typedef void (*WIND_FORCE_CB)(int windForce);typedef void (*WIND_DIRECT_CB)(int windDirection);typedef void (*ANION_CB)(bool isOn);typedef void (*AQS_CB)(bool isOn);typedef void (*CLEAR_FOG_PREV_CB)(bool isOn);typedef void (*CLEAR_FOG_SUF_CB)(bool isOn);typedef void (*INNER_LOOP_CB)(bool isOn);typedef void (*AUTO_MODE_CB)(bool isOn);typedef void (*AC_CB)(bool isOn);typedef void (*AC_MAX_CB)(bool isOn);typedef void (*DUAL_CB)(bool isOn);typedef void (*PM25_CB)(int pm_val,int type);typedef void (*FAN_CB)(bool isOn);class CallBack{public: TEMPERATURE_CB getTemperatureCallback()const{return temp_cb;} void setTemperatureCallback(const TEMPERATURE_CB cb){temp_cb = cb;} WIND_FORCE_CB getWindForceCallback()const{return wind_force_cb;} void setWindForceCallback(const WIND_FORCE_CB cb){wind_force_cb = cb;} WIND_DIRECT_CB getWindDirectionCallback()const{return wind_direct_cb;} void setWindDirectionCallback(const WIND_DIRECT_CB cb){wind_direct_cb = cb;} ANION_CB getAnionCallback()const{return anion_cb;} void setAnionCallback(ANION_CB cb){anion_cb = cb;} AQS_CB getAqsCallback()const{return aqs_cb;} void setAqsCallback(AQS_CB cb){aqs_cb = cb;} CLEAR_FOG_PREV_CB getClearFogPrevCallback(){return clear_fog_prev_cb;} void setClearFogPrevCallback(CLEAR_FOG_PREV_CB cb){clear_fog_prev_cb=cb;} CLEAR_FOG_SUF_CB getClearFogSufCallback(){return clear_fog_suf_cb;} void setClearFogSufCallback(CLEAR_FOG_SUF_CB cb){clear_fog_suf_cb = cb;} INNER_LOOP_CB getInnerLoopCallback(){return inner_loop_cb;} void setInnerLoopCallback(INNER_LOOP_CB cb){inner_loop_cb = cb;} AUTO_MODE_CB getAutoModeCallback(){return auto_mode_cb;} void setAutoModeCallback(AUTO_MODE_CB cb){auto_mode_cb = cb;} AC_CB getACCallback(){return ac_cb;} void setACCallback(AC_CB cb){ac_cb = cb;} AC_MAX_CB getACMaxCallback(){return ac_max_cb;} void setACMaxCallback(AC_MAX_CB cb){ac_max_cb = cb;} DUAL_CB getDualCallback(){return dual_cb;} void setDualCallback(DUAL_CB cb){dual_cb = cb;} PM25_CB getPm25Callback(){return pm25_cb;} void setPm25Callback(PM25_CB cb){pm25_cb = cb;} FAN_CB getFanCallback(){return fan_cb;} void setFanCallback(FAN_CB cb){fan_cb = cb;}private: TEMPERATURE_CB temp_cb; WIND_FORCE_CB wind_force_cb; WIND_DIRECT_CB wind_direct_cb; ANION_CB anion_cb; AQS_CB aqs_cb; CLEAR_FOG_PREV_CB clear_fog_prev_cb; CLEAR_FOG_SUF_CB clear_fog_suf_cb; INNER_LOOP_CB inner_loop_cb; AUTO_MODE_CB auto_mode_cb; AC_CB ac_cb; AC_MAX_CB ac_max_cb; DUAL_CB dual_cb; PM25_CB pm25_cb; FAN_CB fan_cb;};#endif //com_aircondition_callback_interface_h
frameworks/base/core/java/android/app/ContextImpl.java
add:
registerService(AIR_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(AIR_SERVICE); IAirCondition ac =IAirCondition.Stub.asInterface(b); return new AirManager(ac);}});
获取AirManager直接采用context.getSystemService(AIR_SERVICE);
在frameworks/base/services/java/com/android/server/SystemServer.java
try{ServiceManager.addService(Context.AIR_SERVICE, new AirService(context)); }catch(Throwable e){ }
makefile 中添加 libaircondition_jni
LOCAL_PATH:= $(call my-dir)# the library# ============================================================include $(CLEAR_VARS)LOCAL_SRC_FILES := \ $(call all-subdir-java-files) \ com/android/server/EventLogTags.logtags \ com/android/server/am/EventLogTags.logtagsLOCAL_MODULE:= servicesLOCAL_JAVA_LIBRARIES := android.policy conscrypt telephony-commonLOCAL_REQUIRED_MODULES := libaircondition_jniinclude $(BUILD_JAVA_LIBRARY)include $(BUILD_DROIDDOC)
0 0