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层调用。

读者只需要熟悉这部分代码的大体结构和功能即可,后续章节将会详细介绍这部分内容。