Android JNI

摘自:http://blog.csdn.net/free2o/article/details/4493617

Android 系统中一些和硬件相关或者系统底层的服务的操作或者通过外面的软件包实现的功能都会封装成为java 的类以供应用层开发使用,从而是应用层不必关心底层的实现细节,停留在java level 去处理系统操作。在封装的java 类和系统native 实现之间要通过JNI 来实现。 JNI (java native interface)

JNI 的实现比较简单,扩展的类要在系统启动的时候,把封装的类注册到java 虚拟机的环节中,从而java 程序在运行的时候,可以正确的找到相关的类调用相对应的功能模块。例如代码: base/core/jni/server/onload.cpp 文件中的函数 JNI_OnLoad 中就注册了几个类。

 

extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)

{

    JNIEnv* env = NULL;

    jint result = -1;

 

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {

        LOGE("GetEnv failed!");

        return result;

    }

    LOG_ASSERT(env, "Could not retrieve the env!");

 

    register_android_server_KeyInputQueue(env);

    register_android_os_Vibrator(env);

    register_android_server_AlarmManagerService(env);

    register_android_server_BatteryService(env);

    register_android_server_SensorService(env);

    register_android_server_SystemServer(env);

 

    return JNI_VERSION_1_4;

}

  以函数 register_android_server_BatteryService 为例进行分析:

int register_android_server_BatteryService(JNIEnv* env)

{

    jclass clazz = env->FindClass("com/android/server/BatteryService");

 

    if (clazz == NULL) {

        LOGE("Can't find com/android/server/BatteryService");

        return -1;

    }

    /*

      返回类的实例(非静态)域的域 ID

     */

    gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");

    gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");

    gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");

    gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");

    gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");

    gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");

    gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");

    gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");

    gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");

 

    LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");

    LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryLevel == NULL, "Unable to find BatteryService.BATTERY_CAPACITY_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryVoltage == NULL, "Unable to find BatteryService.BATTERY_VOLTAGE_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryTemperature == NULL, "Unable to find BatteryService.BATTERY_TEMPERATURE_PATH");

    LOG_FATAL_IF(gFieldIds.mBatteryTechnology == NULL, "Unable to find BatteryService.BATTERY_TECHNOLOGY_PATH");

 

    clazz = env->FindClass("android/os/BatteryManager");

 

    if (clazz == NULL) {

        LOGE("Can't find android/os/BatteryManager");

        return -1;

    }

    /* 

          从类BatteryManager 取得静态int 类成员 'BATTERY_STATUS_UNKNOWN' 的值付给 gConstants.statusUnknown 

          用类的默认值来初始化全局变量 gConstants 的初始值

    */

    gConstants.statusUnknown = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_STATUS_UNKNOWN", "I"));

 

    gConstants.statusCharging = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_STATUS_CHARGING", "I"));

 

    gConstants.statusDischarging = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_STATUS_DISCHARGING", "I"));

 

    gConstants.statusNotCharging = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_STATUS_NOT_CHARGING", "I"));

 

    gConstants.statusFull = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_STATUS_FULL", "I"));

 

    gConstants.healthUnknown = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNKNOWN", "I"));

 

    gConstants.healthGood = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_GOOD", "I"));

 

    gConstants.healthOverheat = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVERHEAT", "I"));

 

    gConstants.healthDead = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_DEAD", "I"));

 

    gConstants.healthOverVoltage = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVER_VOLTAGE", "I"));

 

    gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz, 

            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));

 

    return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));

}

  在函数的最后一行可以看到函数 jniRegisterNativeMethods 调用,通过jniRegisterNativeMethods 函数向java 虚拟机中注册了类 "com/android/server/BatteryService" 的类名称是 BatteryService ,类所在的package 是 "com/android/server" 注册了native 的函数。 函数的方法在数组 sMethods 中有描述,sMethod 数组如下:

 

static JNINativeMethod sMethods[] = {

     /* name, signature, funcPtr */

{"native_update", "()V", (void*)android_server_BatteryService_update},

};

  在封装的java 类BatteryService 中会声明     private native void native_update(); 函数,这个函数就对应 native 的函数 *)android_server_BatteryService_update。 

   其中 JNINativeMethod  的定义在 jni.h 中,结构如下:

  typedef struct {

       const char * name;

       const char * signature;

       void * fnptr;

  }JNINativeMethod;

  对于JNI 的规范,可以从“ http://linux.computersci.net/articles/jdk1.2/docs/guide/jni/spec/jniTOC.doc.html ” 找到中文版本的规范。通过JNI 层使得java 可以很好的利用已有的代码或者库函数。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值