2.2.2 Log系统的JNI层
JNI层是实现Java层方法最关键的部分。还是以Log系统为例讲解JNI层是如何实现Java层声明的Native方法的。不熟悉JNI的读者可以根据包名和类名定位JNI层文件,对于Log类,其对应的JNI文件是android_util_Log.cpp。
打开android_util_Log.cpp文件,其代码如下:
include"jni.h"//符合JNI规范的头文件,必须包含进来
include"JNIHelp.h"//Android为更好地支持JNI提供的头文件
include"utils/misc.h"
include"android_runtime/AndroidRuntime.h"
/*这里便是Java层声明的isLoggable方法的实现代码。
*JNI方法增加了JNIEnv和jobject两个参数,其余参数和返回值只是将Java参数映射成JNI
的数据类型,然后通过调用本地库和JNIEnv提供的JNI函数处理数据,最后返回给Java层/
static jboolean android_util_Log_isLoggable(JNIEnv*env, jobject clazz,
jstring tag, jint level)
{
……
//这里调用了JNI函数
const char*chars=env->GetStringUTFChars(tag, NULL);
jboolean result=false;
if((strlen(chars)+sizeof(LOG_NAMESPACE))>PROPERTY_KEY_MAX){
……
}else{
//这里调用了本地库函数
result=isLoggable(chars, level);
}
env->ReleaseStringUTFChars(tag, chars);//调用JNI函数
return result;
}
//以下是Java层声明的println_Native方法的实现代码
static jint android_util_Log_println_native(JNIEnv*env, jobject clazz,
jint bufID, jint priority, jstring tagObj, jstring msgObj)
{
const char*tag=NULL;
const char*msg=NULL;
……//省略异常处理代码
if(tagObj!=NULL)
tag=env->GetStringUTFChars(tagObj, NULL);//调用JNI函数
msg=env->GetStringUTFChars(msgObj, NULL);
//调用本地库提供的方法
int res=__android_log_buf_write(bufID,(android_LogPriority)priority, tag, msg);
if(tag!=NULL)
env->ReleaseStringUTFChars(tagObj, tag);//调用JNI函数释放资源
env->ReleaseStringUTFChars(msgObj, msg);//调用JNI函数释放资源
return res;
从这里以看出,JNI层的实现方法只是根据一定的规则与Java层声明的方法做了一个映射,然后可以通过使用本地库函数或JNIEnv提供的JNI函数响应Java层调用。
读者只需要熟悉这部分代码的大体结构和功能即可,后续章节将会详细介绍这部分内容。