资讯专栏INFORMATION COLUMN

使用Log的一些姿势

LancerComet / 438人阅读

摘要:不过,或许是因为实在是太过于普通,所以许多人在使用它的时候就显得非常随意,这些错误的使用姿势却会在不经意间给我们带来不少的大坑。

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,事实上已经造成了不少的性能丢失。正确的使用姿势应该是:

public static final boolean DEBUG = true;

if (DEBUG) {
  Log.v(TAG, "log something");
}
在循环体内部打印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} 的加强版,以方便在开发时用来
操作调试日志。

特点

简单易用的API;

支持输出线程信息;

支持设置LogLevel,方便在生产环境关闭调试用的LOG;

支持将LOG内容写入文件,以便通过文件LOG定位用户反馈的问题;

注意,尽管BLog支持关闭Log的输出,但是在你调用 BLog.v(String) 的时候,其实已经造成了性能
丢失,所以请尽量使用正确的姿势来使用BLog,比如

if (BuildConfig.DEBUG) {
  BLog.v(TAG, "log verbose");
}
Getting Started

GitHub : https://github.com/kaedea/b-log
出处 : 使用 Log 的正确姿势

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/13339.html

相关文章

  • Day09 - Console 调试各种姿势指南

    摘要:调试各种姿势指南作者简介是推出的一个天挑战。现在你看到的是这系列指南的第篇。完整中文版指南及视频教程在从零到壹全栈部落。项目效果各种调试正确姿势的更多用法这个是最常用的,但它还有一些更多功能比如参数支持类似语言的字符串替换模式。 Day09 - Console 调试各种姿势指南 作者:©liyuechun 简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。...

    孙淑建 评论0 收藏0
  • Day09 - Console 调试各种姿势指南

    摘要:调试各种姿势指南作者简介是推出的一个天挑战。现在你看到的是这系列指南的第篇。完整中文版指南及视频教程在从零到壹全栈部落。项目效果各种调试正确姿势的更多用法这个是最常用的,但它还有一些更多功能比如参数支持类似语言的字符串替换模式。 Day09 - Console 调试各种姿势指南 作者:©liyuechun 简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战。...

    wthee 评论0 收藏0
  • Java日志正确使用姿势

    摘要:但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的发生,作为一名严谨的程序员,怎么能让这种事情发生呢所以下面我们就来了解一下关于日志的那些正确使用姿势。级别表示出现了严重错误,程序将会中断执行。 前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中尽情的打印我们需要的信息了。但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的bug发...

    UCloud 评论0 收藏0
  • TiDB 正确使用姿势

    摘要:全局索引的好处是对使用者没有限制,可以到任意大小,不过这意味着,索引信息不一定和实际的数据在一个内。 最近这几个月,特别是 TiDB RC1 发布后,越来越多的用户已经开始测试起来,也有很多朋友已经在生产环境中使用,我们这边也陆续的收到了很多用户的测试和使用反馈。非常感谢各位小伙伴和早期用户的厚爱,而且看了这么多场景后,也总结出了一些 TiDB 的使用实践 (其实 Spanner 的最...

    xavier 评论0 收藏0
  • TiDB 正确使用姿势

    摘要:全局索引的好处是对使用者没有限制,可以到任意大小,不过这意味着,索引信息不一定和实际的数据在一个内。 最近这几个月,特别是 TiDB RC1 发布后,越来越多的用户已经开始测试起来,也有很多朋友已经在生产环境中使用,我们这边也陆续的收到了很多用户的测试和使用反馈。非常感谢各位小伙伴和早期用户的厚爱,而且看了这么多场景后,也总结出了一些 TiDB 的使用实践 (其实 Spanner 的最...

    dreambei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<