JVM_NATIVE

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_h

typedef 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.logtags

LOCAL_MODULE:= services

LOCAL_JAVA_LIBRARIES := android.policy conscrypt telephony-common
LOCAL_REQUIRED_MODULES := libaircondition_jni

include $(BUILD_JAVA_LIBRARY)

include $(BUILD_DROIDDOC)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值