摘自: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 可以很好的利用已有的代码或者库函数。