使用Log的一些姿势

移动开发 Android
LogCat是Android开发者们最熟悉不过的日志打印工具,几乎每一个Android项目里面都包含着大量的Log相关代码。不过,或许是因为Log实在是太过于普通,所以许多人在使用它的时候就显得非常随意,这些错误的使用姿势却会在不经意间给我们带来不少的大坑。

[[176407]]

LOG 是任何一种编程语言的***个API,通常被初学者用来打印 Hello, World!。 有研究显示,

不使用 LOG 或者使用姿势错误的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人***只能把遗产留给自己的猫。毕竟爱情需要书写,不能是一整张白纸。

LogCat是Android开发者们最熟悉不过的日志打印工具,几乎每一个Android项目里面都包含着大量的Log相关代码。不过,或许是因为Log实在是太过于普通,所以许多人在使用它的时候就显得非常随意,这些错误的使用姿势却会在不经意间给我们带来不少的大坑。

Log相关的一些问题

没有关闭调试用的LOG

许多同学喜欢在开发阶段用Log输出当前的一些环境数据,用于调试代码,但是在调试完成后却忘了关闭这些Log,导致发版出去的应用里面还会继续输出这些LOG,这样不仅会造成不必要的性能丢失,也会暴露一些敏感的数据,这些都是我们不愿看到的。

首先,我们要给Log进行分级,规定“DEBUG版本输出哪一些级别的LOG并屏蔽哪一些级别的LOG,而RELEASE版本又输出另一些级别的LOG并屏蔽另一些级别的LOG”,这样在开发阶段能够输出我们调试需要的LOG,而同时又能保证放送的版本能够屏蔽这些敏感的LOG。但是在开发阶段我们不应该特意去注意这些细节,所以必须开发一个Log工具库,在框架层级解决这个需求。

同时,需要注意的是,用于作为“开启/关闭Log”的开关必须是一个常量,而不能是一个变量(使用常量的话,在编译代码的时候,如果常量为false),编译器会直接把调试部分的Log代码直接去掉,而使用变量作为开关的话,这个判断逻辑会继续保留,一方面会造成性能丢失,另一方面在运行时也可以通过Hack手段强行开启这部分Log代码。

另外,“开启/关闭Log”的开关必须写在Log方法外部,也就是说必须先判断“开启/关闭Log”条件,再调用Log方法,因为在调用Log方法的时候已经造成了性能丢失,而且调用方法的时候,会先构造好改方法需要的参数(按照参数顺序从右往左),再调用方法,而许多人喜欢在调用Log方法的时候计算需要打印出来的内容,这里是最容易造成性能丢失的地方。因此,如果为了图方便,写一个Log工具类,在工具类内部去判断是否应该开启或关闭Log,事实上已经造成了不少的性能丢失。正确的使用姿势应该是:

  1. public static final boolean DEBUG = true
  2.  
  3. if (DEBUG) { 
  4.   Log.v(TAG, "log something"); 
  5.  

在循环体内部打印LOG

尽管Log造成的性能损失很小,但是如果在循环体内部循环调用Log方法的话,那总体的丢失的非常可观了,所以不应该在循环体内部使用Log,正确的做法是在循环体内部拼接需要打印的内容,等跳出循环体再一次打印出来。

除了常见的循环体外,还要一个需要注意的场景就是Adapter。ListView/RecyclerView是Android开发中最常用的控件,因此Adapter使用的情景也很多。滚动屏幕的时候,ListView/RecyclerView会在通过Adapter频繁地绑定ItemView和数据,而且这些都是在UI线程里进行的,所以如果在绑定的过程中调用Log,可能会造成明显的卡顿。

至于Log到底会丢失多少性能,一般情况下,Log的性能丢失很小,毕竟是这么常见的系统Api,肯定是身经百战,早就是“best performance”了。不过我曾经有个RecyclerView在MIUI上非常卡,一开始我是RecyclerView布局没优化好,最终定位到Adapter内部的一处Log上,卡顿的地方出现在Log的Native实现。MIUI到底对用户输出的日志做了什么处理呢?非常神奇。

无法获取重要LOG内容

在调试代码的时候,我们经常通过LOG来定位Bug。同理,当线上的版本出现问题的时候,我们也希望能通过LOG来定位问题所在。但是问题是用户的设备上的打印出来的LOG我们根本没有方法获取,唯一的手段就是当用户设备出现问题的时候,把设备借过来连上IDE用LogCat查看输出的LOG……显然这是不可行的。

这种时候,我们可以在打印重要LOG(比如重要路径的触发点、或者一些异常类的信息)的时候,一并把这些信息记录到文件里。在用户反馈系统里面,一并将这些文件上传到我们的用户反馈服务器,这样在处理反馈问题的时候,就能拿到重要的参考日志了。

BLog

BLog 是 Android SDK 的 LOG 工具 {@Link android.util.Log} 的加强版,以方便在开发时用来

操作调试日志。

特点

  1. 简单易用的API;
  2. 支持输出线程信息;
  3. 支持设置LogLevel,方便在生产环境关闭调试用的LOG;
  4. 支持将LOG内容写入文件,以便通过文件LOG定位用户反馈的问题;

注意,尽管BLog支持关闭Log的输出,但是在你调用 BLog.v(String) 的时候,其实已经造成了性能

丢失,所以请尽量使用正确的姿势来使用BLog,比如

  1. if (BuildConfig.DEBUG) {   
  2. BLog.v(TAG, "log verbose"); 

 

责任编辑:庞桂玉 来源: segmentfault
相关推荐

2017-11-09 13:19:51

2019-05-07 10:28:27

2021-10-12 23:10:58

UnsafeJavaJDK

2009-07-21 09:29:27

iBATIS使用

2010-05-10 15:41:38

Unix系统

2023-11-10 08:48:09

Lombok库Java8

2023-10-09 08:14:10

Helm管理应用

2022-04-02 14:43:59

Promethues监控

2015-08-17 15:53:58

Linux桌面

2015-09-23 10:06:37

cocoapods

2011-07-19 18:11:09

iPhone 开发

2009-11-25 10:08:41

Cisco无线路由

2020-02-03 16:03:36

疫情思考

2010-09-28 14:14:19

SQL语句

2011-06-01 16:50:21

JAVA

2009-06-18 14:54:52

Spring AOP

2013-07-02 09:43:02

编程策略

2009-09-21 17:46:25

Hibernate数据

2009-06-25 09:50:32

JSF

2013-07-02 10:18:20

编程编程策略
点赞
收藏

51CTO技术栈公众号