- 最后更新: 2016-03-30
- 修改记录:
- 2015-11-04 初稿
- 2015-11-10 增加日志需求
- 2015-11-14 增加实现细节
- 2016-03-30 图片本地化
1. 简介
在日常的 Android 开发中,日志打印是一项必不可少的操作,我们通过分析打印的日志可以分析程序的运行数据和情况。本文主要介绍了如何更好的使用日志。先来介绍下相关的原理,然后来说说怎么优化开发体验。
2. 哪些形式
System.out.println
这是标准的Java输出方法,相信很多公司都不提倡使用,这里进行列举,目的是为了提醒大家不用。Android Log
Android 自身提供了一个日志工具类,那就是android.util.Log
。使用很简单,如下:
|
|
我们在调试的时候经常会输出这行代码,这个方法有两个参数,一个是TAG,一个是真正要输出的内容。
3. TAG 的选取
TAG 选择虽然没有强制要求,一般来说只要是个字符串就行,但是好的 TAG 策略,可以提高开发体验。
3.1 选用人名
很多人都曾采用人名的形式,比如:
|
|
这样做的目标一是为了过滤方便,当一个人在写一个模块多个文件时,使用这个形式,过滤起来很容易帮助理解程序的执行情况。另外的目的就是为了表明日志周围代码的作者姓甚名谁。
然而,我却不推荐这种人名作为TAG的形式。原因如下:
- 以人名作为关键字过滤,不易确定产生日志的类文件
- 随着某个人模块实现的增加,过滤人名易产生来自其他模块的干扰信息。
3.2 动态选取
还有一种选取方式,就是:
|
|
这样使用,得到的 LOGTAG
的值就是 Settings
。这么做,开发版使用的时候非常方便;但是当应用打包发布时,Settings
这个类进行了混淆之后,类名变成了类似 a,b,c 这样的名称,LOGTAG
则不再是 Settings
这个值了。这样可能造成的问题就是,内部混淆有日志的包,我们无法再通过过滤 Settings
来得到相应的信息。
3.3 静态的 tag
一般比较推荐的形式就是以字符串字面量形式去设置 LOGTAG。如下,在Settings
类中
|
|
4. 屏蔽日志输出
主要是通过两种方式实现的,一个是在编译期时候屏蔽;一个是在运行时中处理。
4.1 运行时屏蔽
通常做法,是自定义一个类
|
|
通过调用 L.i 来输出日志,通过修改 ENABLE_LOG
的值可以方便的切换是否屏蔽日志输出。
注意
|
|
虽然可以屏蔽日志输出,但是并不会屏蔽语句中的代码 getVersion
执行,另外字符串的拼接也会被执行到。
4.2 编译期屏蔽
主要是利用 Proguard
在代码混淆时,去掉相关的日志代码。
|
|
可以用同样的方式来处理原生的日志打印
|
|
下面来个栗子,看看反编译的出来的代码:
先来个测试的代码,其他无关部分都先忽略掉:
|
|
然后使用 proguard
的配置
|
|
生成 apk 之后,反编译,得到 smali 源码:
|
|
无论是运行时日志屏蔽还是编译期,message参数上发生的字符串拼接都依然存在。但是编译期屏蔽减少了方法调用(即方法进出栈操作).
5. 优化实践
本来文章到这里就可以结束了。介绍了原理,接下来小伙伴们就可以愉快的编码了。但是作为有追求的理想青年,我们还是可以利用 log 来提升开发体验的。
对于一个需要重复无数遍的函数,我们需要尽可能的简化
在应用开发中,我们可能需要无数次的写下:
|
|
很多时候,我们仅需要个输出,于是就有了第一个需求,省略 TAG,或者说,我们希望有一个东西可以帮我们定义好TAG,我们只需要写正真有意义的内容就行。
更进一步,虽然现在 IDE 都有了代码自动提示,但是能少打几个字总是好的。我们希望 L
来替代 Log
然后呢,我们希望 log 输出的更加美观。最好输出的有一个 超链接
,点击就能跳转到相应的代码中
==这个功能只支持 Android Studio,Eclipse只能输出,无法跳转==
有时候,我们需要的只是输出一个简单的字符,有时候,我们又希望能把函数调用的堆栈也打印出来。
或者是
最好能支持数据的可视化,而不用手动去拼接字符串或者简单的通过 Object.toString()
来打印对象信息。
json 格式化
数组等数据结构
对应输出
- 其他对象
哦,还有。加个能控制 log的开关,另外能够方便的定制 log 的输出,比如输出到文件或者回传服务器
6. 实现
上面的需求实现的难度并不是很大,这里就大致介绍下实现的思路。
获取当前类名
|
|
输出函数文件信息
|
|
数据可视化实现
array
,map
,set
等容器可以通过遍历显示Object
可以通过反射方式,拿到变量以及变量的类型xml
,json
可以通过自定义格式化来实现
7. 后记
通过这篇文章,给大家介绍了一个日志输出优化的过程。通过实践,说明一个最简单的日志输出都是有很多可以优化的地方;有时候,一些小小的改造,可以极大的提升开发的体验。
最后的最后,你可能不太喜欢这样的日志输出。没关系,相信我们的最终目的是一致的,就是让开发越来越便捷,代码越来越优雅~