你好,游客 登录 注册 搜索
背景:
阅读新闻

Android框架简介

JAVA环境(下)

[日期:2011-10-10] 来源:Linux社区  作者:hongchunhua [字体: ]

上节讲到了JAVA框架代码和应用程序的关系,那么框架代码和驱动层是怎么联系的呢?这就是这一节的内容:JNI

java使用一种叫做jni的技术来支持对C/C++代码的调用,在anroid中jni的代码放在froyo/frameworks/base/core/jni下,当然在java框架代码的目录下还有其他地方也多多少少放了jni代码,大家可以打开源码来看看。

整体关系如下图:

| java应用程序

--------------------------------------- Android系统api

| java框架

    |本地接口声明

--------------------------------------

| JNI
--------------------------------------

| C/C++代码

继续拿来主义,C/C++中调试用printf,内核调试用printk,呵呵,android调试用log,那么我们就分析log的实现。

log的java代码froyo/frameworks/base/core/java/android/util/Log.java,

我们看到所有代码都是调用public static native int println_native(int bufID,
            int priority, String tag, String msg);来实现输出的,这个函数的实现就是C++,调用的方式就是JNI

我们看一下对应的jni代码froyo/frameworks/base/core/jni/android_util_Log.cpp,最终调用的输出函数是

  1. /* 
  2.  * In class android.util.Log: 
  3.  *  public static native int println_native(int buffer, int priority, String tag, String msg) 
  4.  */  
  5. static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,  
  6.         jint bufID, jint priority, jstring tagObj, jstring msgObj)  
  7. {  
  8.     const char* tag = NULL;  
  9.     const char* msg = NULL;  
  10.     if (msgObj == NULL) {  
  11.         jclass npeClazz;  
  12.         npeClazz = env->FindClass("java/lang/NullPointerException");  
  13.         assert(npeClazz != NULL);  
  14.         env->ThrowNew(npeClazz, "println needs a message");  
  15.         return -1;  
  16.     }  
  17.     if (bufID < 0 || bufID >= LOG_ID_MAX) {  
  18.         jclass npeClazz;  
  19.         npeClazz = env->FindClass("java/lang/NullPointerException");  
  20.         assert(npeClazz != NULL);  
  21.         env->ThrowNew(npeClazz, "bad bufID");  
  22.         return -1;  
  23.     }  
  24.     if (tagObj != NULL)  
  25.         tag = env->GetStringUTFChars(tagObj, NULL);  
  26.     msg = env->GetStringUTFChars(msgObj, NULL);  
  27.     int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);  
  28.     if (tag != NULL)  
  29.         env->ReleaseStringUTFChars(tagObj, tag);  
  30.     env->ReleaseStringUTFChars(msgObj, msg);  
  31.     return res;  
  32. }  

当然我们发现最终输出是

  1. int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);  

用力grep了一下代码,结果如下

./system/core/include/cutils/log.h:int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
./system/core/liblog/logd_write.c:int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
./system/core/liblog/logd_write.c:    return __android_log_buf_write(bufID, prio, tag, buf);

这个就是和android专用驱动进行通信的方式,这个分析下去就有点深了,后面分析。

以上三个小节分析了android的JAVA环境,我这里都是简单的抛砖引玉,希望能给大家一点大体的指引,其他修行靠大家了,能成为是一个android程序员是多么幸福的事情,各位已经在幸福中了,我什么时候也可以幸福一把??

linux
【内容导航】
第1页:JAVA环境(上) 第2页:JAVA环境(中)
第3页:JAVA环境(下)
相关资讯       Dalvik  Android开发 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款