Android通用开发——日志常用技术总结
一、Android 日志系统概述
Android 日志系统是开发过程中重要的调试工具,主要通过 android.util.Log
类实现日志输出。
该类提供了多个常用方法,包括 Log.v()
(输出最详细的日志,用于开发调试)、Log.d()
(输出调试信息,建议发布时移除)、Log.i()
(输出重要运行信息)、Log.w()
(输出潜在问题警告)、Log.e()
(输出错误信息,通常不影响应用继续运行)以及 Log.wtf()
(输出严重错误,可能导致应用崩溃)。
但是在大型项目中,会进行对Log进行一步一步的封装来扩充优化来满足工作中对Log的日志要求
public class OMSLogger {private static boolean isLoggable = true;private static final String VERSION_NAME = BuildConfig.versionName; //软件版本名private static final String VERSION_CODE = BuildConfig.versionCode; //软件版本号private static final String GIT_HASH = BuildConfig.GIT_HASH; //Git hashprivate static final String LOG_PREFIX = "versionName:" + VERSION_NAME + " versionCode:" + VERSION_CODE + " Git-hash:" + GIT_HASH;/*** 获取Log的prefix* 包含软件版本名,版本号,Git hash*/public static String getPrefix() {return LOG_PREFIX;}/*** 打印info级别的log* 包含软件版本名,版本号,Git hash*/public static void i(String tag, String log) {if (isLoggable) {OMSLogHelper.getInstance().i(tag, LOG_PREFIX + " " + log);}}/*** 打印debug级别的log* 包含软件版本名,版本号,Git hash*/public static void d(String tag, String log) {if (isLoggable) {OMSLogHelper.getInstance().d(tag, LOG_PREFIX + " " + log);}}/*** 打印warn级别的log* 包含软件版本名,版本号,Git hash*/public static void w(String tag, String log) {if (isLoggable) {OMSLogHelper.getInstance().w(tag, LOG_PREFIX + " " + log);}}/*** 打印error级别的log* 包含软件版本名,版本号,Git hash*/public static void e(String tag, String log) {if (isLoggable) {OMSLogHelper.getInstance().e(tag, LOG_PREFIX + " " + log);}}/*** 打印error级别的log* 包含软件版本名,版本号,Git hash*/public static void e(String tag, Throwable tr) {if (isLoggable) {OMSLogHelper.getInstance().e(tag, LOG_PREFIX , tr);}}/*** 打印error级别的log* 包含软件版本名,版本号,Git hash*/public static void e(String tag, String msg, Throwable tr) {if (isLoggable) {OMSLogHelper.getInstance().e(tag, LOG_PREFIX + " " + msg , tr);}}
}
public class OMSLogHelper {private volatile static OMSLogHelper INSTANCE = null;private OMSLogHelper() {}public synchronized static OMSLogHelper getInstance() {if (null == INSTANCE) {synchronized (OMSLogHelper.class) {if (null == INSTANCE) {INSTANCE = new OMSLogHelper();}}}return INSTANCE;}public void i(String TAG, String log) {Log.i(TAG, log);}public void d(String TAG, String log) {Log.d(TAG, log);}public void w(String TAG, String log) {Log.w(TAG, log);}public void e(String TAG, String log) {Log.e(TAG, log);}public void e(String TAG, String log, Throwable tr) {Log.e(TAG, log, tr);}
}
二、Android Studio Logcat工具使用
上述中的TAG,level都可以通过Logcat工具进行过滤,下面我将介绍Logcat的具体使用
Android Studio 内置的 Logcat 工具可用于实时查看设备或模拟器的系统日志和应用日志。
通过底部工具栏的 “Logcat” 标签、菜单栏的 View → Tool Windows → Logcat 或快捷键(Alt+6 或 Command+6)可以打开 Logcat 界面。
该界面包含设备选择下拉框、应用进程选择下拉框、日志级别筛选器、搜索框、日志显示区域和日志配置菜单。
其中Logcat 的搜索框功能非常强大,远不止简单的关键字搜索。它基于一种名为 “查询语言” 的语法,允许你使用特定的键值对和操作符来构建精确的过滤器。
1. tag
- 按标签过滤
功能:只显示指定标签(Tag)的日志。
示例:
tag:MyActivity
- 显示所有 Tag 为 MyActivity 的日志。tag:BLE
- 显示所有 Tag 包含 BLE 的日志(注意:默认是模糊匹配)。
技巧:通常与类名绑定,例如
private static final String TAG = “MainActivity”;
,这样就能快速聚焦到某个特定类的所有日志。
2. level
- 按级别过滤
功能:只显示指定级别及更高级别的日志。级别从低到高为:
V
(Verbose),D
(Debug),I
(Info),W
(Warn),E
(Error),A
(Assert),F
(Fatal)。示例:
level:error
- 只显示 Error 和 Fatal 级别的日志(因为 Error 比 Fatal 级别低,所以也会被包含)。level:debug
- 显示从 Debug 到 Fatal 的所有日志(即不显示最繁琐的 Verbose)。
3. package
- 按应用包名过滤
功能:只显示指定包名的应用的日志。
特殊值:
package:mine
- 极其常用!这是一个快捷方式,会自动过滤出当前 Android Studio 项目中build.gradle
里定义的applicationId
(即你的应用)的日志。package:com.example.myapp
- 显示指定包名com.example.myapp
的应用日志。
技巧:在连接了多个设备或模拟器,或者系统日志非常多时,用
package:mine
可以瞬间只看到自己应用的日志,世界立刻清净。
4. message
- 按日志内容过滤
功能:在日志消息体(Message)中搜索包含特定内容的行。
示例:
message:onCreate
- 显示所有消息中包含 “onCreate” 的日志。message:”Network error”
- 显示包含完整短语 “Network error” 的日志(使用引号保证短语不被拆开)。
注意:如果你不指定任何键,直接输入文本(如
onCreate
),Logcat 默认会在 message 和 tag 两个字段中搜索。
6. age
- 按时间过滤
功能:显示指定时间范围内生成的日志。单位可以是
s
(秒),m
(分钟),h
(小时)。示例:
age:30s
- 只显示最近 30秒 内的日志。age:5m
- 只显示最近 5分钟 内的日志。
应用场景:复现一个刚刚发生的、有时效性的 bug 时非常有用,可以清除旧日志后使用此过滤器。
熟练掌握这些过滤语法,将彻底改变你使用 Logcat 的方式,让你从日志的“海洋”中快速捞出你需要的那根“针”,极大提升开发调试效率。
三、Logcat高级技巧与操作符
1. 逻辑操作符:AND
, OR
, NOT
(-
)
AND (与):空格 就是 AND。tag:MyTAG level:error
表示 “Tag 是 MyTAG 并且 级别是 Error”。
NOT (非):使用 -
(减号)。tag:MyTAG -level:debug
表示 “Tag 是 MyTAG 并且 级别不是 Debug”。
OR (或):使用 OR
(必须大写)。tag:VMgr OR tag:Net
表示 “Tag 是 VMgr 或者 Tag 是 Net”。
2. 正则表达式
功能:使用正则表达式进行更复杂、更灵活的匹配。
语法:在
value
部分使用~
符号前缀来表示后面跟的是正则表达式。示例:
tag:~.*ViewModel
- 显示所有 Tag 以 ViewModel 结尾 的日志(.*
是正则,表示任意字符任意次数)。message:~OOM|OutOfMemory
- 显示消息中包含 “OOM” 或 “OutOfMemory” 的日志。
3. 转义特殊字符
如果你的搜索内容包含 Logcat 语法中的特殊字符(如冒号
:
、空格、引号),可以用双引号 "
将其引起来。示例:
message:"user:id:1234"
- 搜索包含完整字符串user:id:1234
的消息。
四、具体实战示例
假设你的应用包名为 com.autoai.app
,并且你正在排查一个网络请求在 NetworkModule
类中发生的错误。
工作流程如下:
只看自己应用的错误和警告:
package:mine level:error
或更宽泛一点package:mine level:warning
查看某个特定标签的所有级别日志(常用于观察一个类的完整生命周期):
tag:NetworkModule
组合过滤:查看
NetworkModule
标签下的所有非 Verbose 日志:tag:NetworkModule -level:verbose
复杂场景:查看来自
AuthVM
或NetworkVM
标签的 Error 日志:(tag:AuthVM OR tag:NetworkVM) level:error
超级精准过滤:查看最近1分钟内,包名是
com.autoai.app
且消息中包含 “Timeout” 或 “Socket” 的 Error 日志:age:1m package:com.autoai.app message:~Timeout|Socket level:error
总结
Android日志系统通过封装原生Log类(如OMSLogger)为日志注入版本等上下文信息实现集中化可追溯管理,并需结合Logcat的高级过滤语法(如package/tag/level及逻辑操作符)才能从海量信息中精准高效地定位问题,最终提升开发和排查效率。这也是开发者必不可少的。