4、Logcat过滤技巧:按标签(tag)过滤、按优先级过滤、按进程ID(PID)过滤、组合过滤条件。
说实话,刚接触Android开发那会儿,我最怕的就是看Logcat。满屏滚动的日志,眼睛都快看花了,就是找不到自己那条打印。后来带我的老大哥丢给我一句话:「小伙子,Logcat不是用来看的,是用来筛的。」
嗯,今天我就把这套「筛」的本事,原原本本教给你。
4.1 按标签(Tag)过滤:精准定位模块
Tag是什么?说白了就是你代码里Log.d()、Log.i()的第一个参数。我习惯用类名或者模块名,比如MainActivity、NetworkModule。这样一眼就知道日志来自哪里。
在命令行里,用-s参数指定Tag:
adb logcat -s MainActivity
这条命令只显示Tag为MainActivity的日志。其他的一概不显示。干净利落。
如果你想同时看多个Tag,用逗号分隔:
adb logcat -s MainActivity,NetworkModule
我在项目中遇到过一个问题:某个第三方库疯狂打印日志,把我的关键信息全淹没了。当时我就是用-s只保留自己模块的Tag,瞬间世界清净了。
tag:MainActivity,效果和命令行一样。我个人更推荐用这个,因为可以随时修改。
4.2 按优先级过滤:只看你想看的级别
Android日志有6个优先级,从低到高分别是:
| 优先级 | 含义 | 常用场景 |
|---|---|---|
| V | Verbose(详细) | 开发调试时最细的信息 |
| D | Debug(调试) | 调试信息,我一般用这个 |
| I | Info(信息) | 正常流程提示 |
| W | Warn(警告) | 可能有问题,但没崩溃 |
| E | Error(错误) | 出错了,需要关注 |
| F | Fatal(致命) | 要崩了,赶紧看 |
命令行里用*:优先级来过滤。比如只看Error及以上:
adb logcat *:E
这条命令会显示所有Tag的Error和Fatal日志。你想想看,如果满屏都是V和D,你根本找不到重点。直接上*:E,问题一目了然。
我曾经有一次线上bug排查,用户反馈App闪退。我远程连上日志,直接*:F,一秒就定位到了空指针异常。要是从头翻V日志,估计得翻到下班。
*:W,会显示W、E、F三种。不会显示V和D。这个逻辑别搞混了。
4.3 按进程ID(PID)过滤:锁定单个App
有时候你开了好几个App,日志混在一起。这时候按PID过滤就派上用场了。
先找到目标App的PID:
adb shell ps | grep com.example.myapp
假设返回的PID是12345,然后:
adb logcat --pid=12345
这样只显示这个进程的日志。其他App的日志一概不显示。
嗯,这里要注意:PID每次重启App都会变。所以如果你经常用,我建议写个小脚本自动抓PID。或者直接用Android Studio,它自动帮你绑定了当前运行的进程。
4.4 组合过滤条件:真正的杀手锏
单独用上面任何一种,都还不够爽。真正的精髓在于组合。
比如我只想看MainActivity这个Tag的Error日志:
adb logcat MainActivity:E *:S
这条命令的意思是:MainActivity这个Tag显示E及以上级别,其他所有Tag(*:S)静默(Silent,即不显示)。
再比如,我想看PID为12345的进程里,所有Warn以上的日志:
adb logcat *:W --pid=12345
你还可以再加个Tag:
adb logcat NetworkModule:W *:S --pid=12345
这就只显示PID 12345进程里,Tag为NetworkModule的Warn及以上日志。精准到极致。
adb logcat [Tag:优先级] [*:优先级] [--pid=进程ID]你可以自由组合,顺序无所谓。但记住:
*:S是「关掉其他所有」,配合特定Tag使用效果最佳。
4.5 避坑指南:我踩过的那些坑
我曾经犯过一个低级错误:在命令行里写adb logcat -s MainActivity:E,结果发现什么日志都没有。后来才反应过来,-s参数后面只能跟Tag,不能带优先级。正确的写法是adb logcat MainActivity:E *:S。
还有一次,我同时过滤了Tag和PID,但忘了PID已经变了。折腾了半小时,最后发现App重启后PID早换了。从那以后,我每次用PID过滤前,都会先确认一下进程是否还活着。
另外,如果你在Android Studio里用Logcat,有个隐藏功能:按住Ctrl键点击Tag,可以直接跳转到源码中打印日志的那一行。这个我用了两年才发现,分享给你。
4.6 实战:一个完整的排查流程
假设现在有个bug:用户点击登录按钮后,App没反应。我会这样操作:
- 先打开Logcat,用
*:E看看有没有明显错误。 - 如果没有,缩小范围到登录模块的Tag,比如
LoginPresenter:E *:S。 - 还是没找到?把优先级降到W,
LoginPresenter:W *:S。 - 如果还不行,可能是网络问题。再加一个网络模块的Tag:
LoginPresenter:W,NetworkModule:W *:S。 - 最后,确认当前进程的PID,加上
--pid=xxx,排除其他App干扰。
这一套组合拳下来,99%的问题都能在5分钟内定位。剩下的1%?嗯,那可能是硬件问题或者玄学,咱们下次再聊。
Log.d(TAG, "xxx"),TAG定义为类名.class.getSimpleName()。这样不管谁接手,都能用Tag快速定位。团队协作时,这个习惯能省下大量沟通成本。
好了,过滤技巧就这些。说白了就是三个维度:Tag、优先级、PID。组合起来用,Logcat就是你的显微镜。下次遇到满屏日志别慌,先想想怎么「筛」。