当前位置:操作系统 > 安卓/Android >>

Android应用程序框架层和系统运行库层日志系统源代码分析

在开发Android应用程序时,少不了使用Log来监控和调试程序的执行。在上一篇文章Android日志系统驱动程序Logger源代码分析中,我们分析了驱动程序Logger的源代码,在前面的文章浅谈Android系统开发中Log的使用一文,我们也简单介绍在应用程序中使Log的方法,在这篇文章中,我们将详细介绍Android应用程序框架层和系统运行库存层日志系统的源代码,使得我们可以更好地理解Android的日志系统的实现。
           我们在Android应用程序,一般是调用应用程序框架层的Java接口(android.util.Log)来使用日志系统,这个Java接口通过JNI方法和系统运行库最终调用内核驱动程序Logger把Log写到内核空间中。按照这个调用过程,我们一步步介绍Android应用程序框架层日志系统的源代码。学习完这个过程之后,我们可以很好地理解Android系统的架构,即应用程序层(Application)的接口是如何一步一步地调用到内核空间的。
           一. 应用程序框架层日志系统Java接口的实现。
           在浅谈Android系统开发中Log的使用一文中,我们曾经介绍过Android应用程序框架层日志系统的源代码接口。这里,为了描述方便和文章的完整性,我们重新贴一下这部份的代码,在frameworks/base/core/java/android/util/Log.java文件中,实现日志系统的Java接口:
  
 [color=amily:Consolas,'Courier]
 
[java] view plaincopy
 

 

................................................ 
  
 public final class Log { 
  
 ................................................ 
  
     /**
     * Priority constant for the println method; use Log.v.
         */ 
     public static final int VERBOSE = 2; 
  
     /**
     * Priority constant for the println method; use Log.d.
         */ 
     public static final int DEBUG = 3; 
  
     /**
     * Priority constant for the println method; use Log.i.
         */ 
     public static final int INFO = 4; 
  
     /**
     * Priority constant for the println method; use Log.w.
         */ 
     public static final int WARN = 5; 
  
     /**
     * Priority constant for the println method; use Log.e.
         */ 
     public static final int ERROR = 6; 
  
     /**
     * Priority constant for the println method.
         */ 
     public static final int ASSERT = 7; 
  
 ..................................................... 
  
     public static int v(String tag, String msg) { 
         return println_native(LOG_ID_MAIN, VERBOSE, tag, msg); 
     } 
  
     public static int v(String tag, String msg, Throwable tr) { 
         return println_native(LOG_ID_MAIN, VERBOSE, tag, msg + '\n' + getStackTraceString(tr)); 
     } 
  
     public static int d(String tag, String msg) { 
         return println_native(LOG_ID_MAIN, DEBUG, tag, msg); 
     } 
  
     public static int d(String tag, String msg, Throwable tr) { 
         return println_native(LOG_ID_MAIN, DEBUG, tag, msg + '\n' + getStackTraceString(tr)); 
     } 
  
     public static int i(String tag, String msg) { 
         return println_native(LOG_ID_MAIN, INFO, tag, msg); 
     } 
  
     public static int i(String tag, String msg, Throwable tr) { 
         return println_native(LOG_ID_MAIN, INFO, tag, msg + '\n' + getStackTraceString(tr)); 
     } 
  
     public static int w(String tag, String msg) { 
         return println_native(LOG_ID_MAIN, WARN, tag, msg); 
     } 
  
     public static int w(String tag, String msg, Throwable tr) { 
         return println_native(LOG_ID_MAIN, WARN, tag, msg + '\n' + getStackTraceString(tr)); 
     } 
  
     public static int w(String tag, Throwable tr) { 
         return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr)); 
     } 
      
     public static int e(String tag, String msg) { 
         return println_native(LOG_ID_MAIN, ERROR, tag, msg); 
     } 
  
     public static int e(String tag, String msg, Throwable tr) { 
         return println_native(LOG_ID_MAIN, ERROR, tag, msg + '\n' + getStackTraceString(tr)); 
     } 
  
 .................................................................. 
     /** @hide */ public static native int LOG_ID_MAIN = 0; 
     /** @hide */ public static native int LOG_ID_RADIO = 1; 
     /** @hide */ public static native int LOG_ID_EVENTS = 2; 
     /** @hide */ public static native int LOG_ID_SYSTEM = 3; 
  
     /** @hide */ public static native int println_native(int bufID, 
         int priority, String tag, String msg); 
 } 
          定义了2~7一共6个日志优先级别ID和4个日志缓冲区ID。回忆一下Android日志系统驱动程序Logger源代码分析一文,在Logger驱动程序模块中,定义了log_main、log_events和log_radio三个日志缓冲区,分别对应三个设备文件/dev/log/main、/dev/log/events和/dev/log/radio。这里的4个日志缓冲区的前面3个ID就是对应这三个设备文件的文件描述符了,在下面的章节中,我们将看到这三个文件描述符是如何创建的。在下载下来的Android内核源代码中,第4个日志缓冲区LOG_ID_SYSTEM并没有对应的设备文件,在这种情况下,它和LOG_ID_MAIN对应同一个缓冲区ID,在下面的章节中,我们同样可以看到这两个ID是如何对应到同一个设备文件的。
  
            在整个Log接口中,最关键的地方声明了println_native本地方法,所有的Log接口都是通过调用这个本地方法来实现Log的定入。下面

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,