本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Logcat的缺陷
Logcat
是Android平台默认日志工具, 方便且好用. 但它也有不足够之处.
Logcat
日常使用中需要注意的事项:
Logcat
的tag
和message
在Android 26之前有长度的限制:- 在Android 26之前,
tag
长度最大为23个字符, 超出的会自动截取丢掉;message
的最大长度为4096个字符, 超出的会被自动丢掉.
而在Android 26之后, tag
的长度限制被取消掉, 但是message
的长度限制还在. 这就存在当日志消息太长时, 会导致超过长度限制之后的消息会丢失.
Timer: Logcat的完美替代方案
Logcat
的替代解决方案是: Timber
, 大神jake wharton的偶然而为的杰作.
Timber
是Android平台日志工具, 基于Android常规的Log类, 提供了小但可扩展的API.
日志行为可以通过添加Tree
实例进行添加. 你可以通过调用Timber.plant
函数安装新的实例. Tree
的安装应该尽可能的早. 应用的onCreate
是最符合逻辑的地方.
DebugTree
会自动的找出被调用类并且使用该类的名字作为标签. 因为标签比较多样, 当和像Pidcat这样的日志阅读器耦合时, 它工作的非常良好.
默认情况下没有任何Tree
实现是安装了的, 因为每一次在生产中打印日志, 就会出现很大问题.
- Timber提供了接口去扩展并接入别的日志工具.
/** Return whether a message at `priority` should be logged. */
@Deprecated("Use isLoggable(String, int)", ReplaceWith("this.isLoggable(null, priority)"))
protected open fun isLoggable(priority: Int) = true
/** Return whether a message at `priority` or `tag` should be logged. */
protected open fun isLoggable(tag: String?, priority: Int) = isLoggable(priority)
/**
* Write a log message to its destination. Called for all level-specific methods by default.
*
* @param priority Log level. See [Log] for constants.
* @param tag Explicit or inferred tag. May be `null`.
* @param message Formatted log message.
* @param t Accompanying exceptions. May be `null`.
*/
protected abstract fun log(priority: Int, tag: String?, message: String, t: Throwable?)
同时默认实现了LogcatTree
来使用Logcat
打印日志.
-
LogcatTree
对于log的处理: 在Android 26之前自动截取前23个字符, 避免了IllegalArgumentException
. 在Android 26之后, 维持了tag
的原样. -
LogcatTree
对于message的处理: 如果message的长度超过了4096, 会将message每4096个字符打印一下, 直到message的结束. -
Timber
是线程安全的, 通过@Volatile private var treeArray = emptyArray<Tree>()
和synchronized(trees)
实现的诸如Timber#plant(Tree)
,Timer#forest()
,Timer#uproot(Tree)
和Timer#uprootAll()
等函数来保证. -
Timber也默认提供了Lint工具来检测关于格式化
String
相关的代码, 诸如TimberArgCount
,TimberArgTypes
,TimberTagLength
,LogNotTimber
,StringFormatInTimber
,BinaryOperationInTimber
,TimberExceptionLogging
.
Timer通过在Application#onCreate
中调用Timer#plant(Tree)
或者Timer#plant(varargs Tree)
来植入1个或多个Tree来打印日志.