六种不同级别的Log

在Android中支持六种Log类型,分别为Verbose,Info,Debug,Warn,Error和Assert。

  1. Verbose英文含义是冗长的,啰嗦的。Verbose用来记录不重要的,一般的信息,通常不需要关注。
  2. Info中通常记录一些需要用户关注的消息,重要程度比Verbose高。
  3. Warn中则记录警告信息,这类信息通常表示应用执行过程中出现了一些问题,这些问题并不会导致整个应用崩溃,但可能会导致一些业务不能正常执行,因此需要用户重点关注,其重要程度比Info高。
  4. Error则表示应用执行时出现无法处理的严重错误,通常会导致程序无法继续运行,业务中断等严重故障,需要由用户处理,其重要程度比Warn高。
  5. Assert表示断言失败后的错误消息,这类错误原本是不可能出现的错误,现在却出现了,是极其严重的错误类型。
    Verbose,Info,Warn,Error和Assert五类Log的重要程度排序如下。
    Assert > Error > Warn > Info > Verbose
  6. Debug类型没有重要程度的含义,它表示应用的调试信息。

在应用中记录Log

在android.util包中提供了一个Log类,Log类中有一系列的static方法,在应用中可以使用这些方法来记录Log。
android.util.Log类提供的static方法列举如下。

public static int v(String tag, String msg);public static int v(String tag, String msg, Throwable tr);public static int d(String tag, String msg);public static int d(String tag, String msg, Throwable tr);public static int i(String tag, String msg);public static int i(String tag, String msg, Throwable tr);public static int w(String tag, String msg);public static int w(String tag, Throwable tr)public static int w(String tag, String msg, Throwable tr);public static int e(String tag, String msg);public static int e(String tag, String msg, Throwable tr);public static int wtf(String tag, String msg);public static int wtf(String tag, Throwable tr)public static int wtf(String tag, String msg, Throwable tr);

可以看到一共有14个static方法,这14个方法分为六种类型,每种类型又有两个或三个重载的方法。
这六种类型的static方法分别对应六种类型的日志,方法名就是对应日志类型的首字母(wtf除外,wtf表示What a Terrible Failure,相当于不可能发送的错误,含义和Assert相同)。

  • Log.v():用来记录Verbose类型日志
  • Log.d():用来记录Debug类型日志
  • Log.i():用来记录Info类型日志
  • Log.w():用来记录Warn类型日志
  • Log.e():用来记录Error类型日志
  • Log.wtf():用来记录Assert类型日志

参数tag,msg和tr的含义如下:

  • tag:日志的标签,通常用来标识日志的来源,例如可以用应用名作为tag表示该日志是由某个应用记录的,也可以使用Activity或者类名作为tag表示产生该日志信息的类。tag还可以很方便的用来筛选日志。
  • msg:日志的具体内容
  • tr:需要记录在日志中的异常对象,会记录该异常对象中的message以及该异常产生时的函数堆栈。
    如下两行代码在Eclipse中显示的日志信息如图所示。
Exception e = new Exception("An exception occurred");Log.i("tag", "Log a message", e);

在使用android.util.Log类时需要注意的是,三个参数在传入空字符串或null时的表现不同。
对tag参数,无论输入是null或”“,日志中tag字段均为空白,msg信息可以正常显示。
如下代码在Eclipse中显示的日志信息如图所示

Log.v("v", "1");Log.v("", "2");Log.v(null, "3");

对只有两个参数方法中的msg参数,如果输入”“,日志中不会显示任何信息。如果输入null,则会抛出空指针异常。如图所示。

对有三个参数方法中的msg参数,如果输入”“,则日志中只会显示tr中相关的信息。如果输入null,则在显示tr的异常消息前会显示一行内容为”null”的字符串,如图所示。

对tr参数,如果输入null,则“几乎”相当于执行了没有tr参数的方法,唯一不同的地方在于,如果msg参数也为null,则会显示一行内容为”null”的字符串。而在没有tr参数的情况下,如果msg参数为null,则会抛出异常。
查看android.util.Log类源码可以看到,所有的static方法都是调用println_native方法来输出日志信息的。println_native方法原型如下。最后一个参数就是要输出的日志信息内容。

public static native int println_native(int bufID, int priority, String tag, String msg);

当使用两个参数的static方法时,直接将msg参数作为println_native方法最后一个参数的入参。当使用三个参数的static方法时,将“msg+’\n’+getStackTraceString(tr)“作为println_native方法最后一个参数的入参。
在getStackTraceString()中有这样一段代码,也就是说如果tr参数为null,getStackTraceString(tr)返回的是空串。“msg+’\n’+getStackTraceString(tr)“就等于“msg+’\n’“,这时如果msg是空串,则最终结果是”\n”,如果msg是null,则最终结果是”null\n”(null在做加号运算时会自动变成字符串”null”),结果不可能是null,执行println_native时也就不会抛出异常。

if (tr == null) {    return "";}

综上所述,可以有如下结论。

  1. tag字段如果不需要可以使用空串或null
  2. 如果使用两个参数的方法,msg参数既不能为空串(空串没有异常,但什么也不显示,没有任何意义),也不能为null。如果使用三个参数的方法,msg参数可以为空串,表示只需要显示异常信息,不需要额外的信息(msg为null时会显示一行null,同样没有任何意义)。
  3. tr参数如果不需要可以使用null,但这同样没有意义,直接使用不带tr参数的方法即可。
    特别需要注意的是,在使用两个参数的方法时,msg参数一定不能为null,否则会导致程序执行异常。

Log信息的显示

通过android.util.Log类打印的信息会输出到/dev/log/main设备文件中,连接adb shell 后,可以直接通过cat /dev/log/main来查看Log信息,也可以在命令行窗口中通过adb logcat命令来查看。 adb logcat命令支持Log信息的过滤和输出格式设定,还支持将Log信息输出到文件中。其详细用法可以通过adb logcat –help命令查看。
更常用的查看Log信息的方法是在Eclipse中的LogCat窗口中直接查看。
在Eclipse中使用不同的颜色来区分不同类型的日志。默认颜色设置如下。
Verbose用黑色显示,Debug用蓝色显示,Info用绿色显示,Warn用橙色显示,Error和Assert用红色显示。
在Preferences菜单中可以对不同Log类型的颜色进行设置。

在Eclipse和Android Studio中支持Log类型的筛选。在LogCat窗口的右侧有如下所示的下拉框,如图所示。

从上到下按照verbose,debug,info,warn,error,assert的顺序排列。重要程度从低到高(Eclipse认为debug的重要程度介于verbose和info之间)。

需要注意的是,当选择某个类型时,并不是只显示该类型的信息,而是显示该类型以及该类型下方所有的类型的Log,也就是显示重要程度大于等于所选类型的Log信息。例如选择了warn,则会显示warn,error和assert类型的Log信息。

最佳实践

在实际项目中,需要记录Log时通常并不会直接使用android.util.Log类的static方法,而是再封装一个自己的Log类,在这个Log类中调用android.util.Log类的static方法,在需要记录Log时调用封装的Log类。这样做有如下几个好处。

  1. 对tag进行控制。应用中如果让每个需要记录Log的地方自行设置tag,会导致每个消息的tag都不一样。tag起不到应有的作用。相反,在封装的Log类中可以将tag统一起来,约束只使用若干固定的tag。增加,删除和修改tag都会非常方便。
  2. 增加Log全局开关。在封装的Log类中可以增加开关,通过一个boolean参数就可以控制所有的Log的显示和关闭。还可以单独控制某个类型或某个tag的Log的显示和关闭。
  3. 在调用android.util.Log两个参数的static方法时,如果msg参数为null会导致空指针异常。在封装的Log中可以对参数进行判断,如果msg为null时不处理。避免出现程序异常。

更多相关文章

  1. 在cocos2dx里访问/互调android里的activity方法/变量
  2. Android基础 : Android(安卓)Service[转]
  3. Android(安卓)HTTP实例 使用GET方法和POST方法发送请求
  4. Android(安卓)SQLite教程:内部架构及SQLite使用办法
  5. Android在开发中的实用技巧之Parcelable的使用以及如何传递复杂
  6. Android(安卓)RecyclerView嵌套的滑动冲突问题
  7. 利用WebView通过javascript调用android java方法
  8. Android自定义控件系列九:从源码看Android触摸事件分发机制
  9. 条件数据库Android:sqllite的简单使用

随机推荐

  1. Android(安卓)MapView 申请apiKey
  2. Android(安卓)图片加水印
  3. 预显示TextView
  4. Android的一些开源项目集锦 以备以后研究
  5. Android游戏开发实践指南(华章程序员书库
  6. androidTV 9.0 开发调用系统jar异常报错,j
  7. Android(安卓)之 自动提示功能(AutoCompl
  8. Creating Android(安卓)live wallpaper[
  9. android 4中新增的日历处理相关API
  10. 使用valgrind检测Android(安卓)native程