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
原创粉丝点击