Android提供了用户级轻量的LOG机制,它的实现贯穿了Java,JNI,本地c/c++实现以及LINUX内核驱动等Android的各个层次,而且还足够简单清晰,是一个相当不错的解读案例。本系列文章针对LOG机制的内部实现机理进行解读,本文是系列之二,解读Android的Java程序中如何输出LOG信息到LOG的体系中。
LOG输出帮助类
Android的Java程序通过android.util.Log类来输出Log,下图列出了我们常用的Log的静态方法。
一般,要输出Log信息,可直接调用Log.v()/Log.d()/Log.i()/Log.w()/Log.e()等类方法。这里之所以有这么多有区分的方法,这也是Log的分类。Log的分类就如同Log的静态常量成员定义的那样,而Log的优先级按照数字大小排列,数字大的优先级高。而Log.wtf()记录的则是非常致命的FAULT信息(What a Terrible Failure),报这个错误,不光是在Log里记录,还要在界面上有提示,并可能杀死当前的进程。
有了这些分类,如果要输出的LOG优先级低于当前设置的优先级,则该Log信息不会显示。一般的,在Java程序中用Log的方法打印Log之前,应先用isLoggable()判断一下,该级别是否能被记录。
另外,用Log.println()能达到与Log.v()/Log.d()/…等方法同样的输出效果,只是在用它时,要指定对应的优先级。
类Log的实现
类android.util.Log的实现是比较简单的。
类android.util.Log的构造函数是私有的,并不会被实例化,只是提供了静态的属性和方法。
而android.util.Log的各种Log记录方法的实现都依赖于native的实现println_native(),Log.v()/Log.d()/Log.i()/Log.w()/Log.e()最终都是调用了println_native()。如Log.d()的实现:
public static int d(String tag, String msg) { return println_native(LOG_ID_MAIN, DEBUG, tag, msg); }
Native方法println_native()是通过JNI在c/c++中实现的,详情参阅本系列之三:JNI及c/c++ 域写设备文件。