今天介绍几个平时工作和学习当中经常使用的调试技巧,这些都是我自己平时在开发和调试过程中使用频率非常高的方法,如果其中任意一条能够对各位有所帮助,对我来说是一件非常值得开心的事。
当然如果你也有好用的调试方法,欢迎留言。
1. am系列命令
am命令的原理,在以后会有专门的文章来分析,这里只是列出一些平时好用的命令,方便调试问题,比较有代表性的几个am命令:
am start xxx : 可以方便拉起系统中activity组件,这个命令有很多参数,有时可以用来模拟代码里使用Intent打开activity,比如设置启动flag等
am restart : 这个命令会让android系统systemserver进程重启,相当于java虚拟机之上的部分重启。在调试时更新了jar包或apk时可以用这个命令替代笨重的reboot而快速重启生效
am force-stop [package]: 这个命令可以用来强杀指定的包名下所有的进程并清理掉相关组件信息
2. dumpsys命令
上一篇文章里介绍过dumpsys的实现原理,这里接着列出一些我经常使用的dumpsys子命令(当然你可以直接使用dumpsys, 但是它会输出所有的信息,不便于我们查看当前有用的东西):
dumpsys activity activities : 这个命令会将当前系统中的activity栈,task栈信息全部列出,当前系统中所有activity信息,一目了解
dumpsys activity processes : 以进程为单位列出当前系统中所有进程的相关信息,包括进程状态以及进程中包含的所有组件信息
dumpsys meminfo : 列出当前系统中内存信息
dumpsys子命令还有很多,建议大家多去尝试,然后才能在最合适的场景想到最合适的命令,提高debug效率。
3. getCallingPid()
这是Binder.java的方法。调试过framework代码的朋友应该都知道,Android系统framework最重要的工作就是提供了各种各样的系统service,通常来讲,这些service都不会只被
一个应用进程通过binder远程调用,有时在调试时想知道service的某个方法是被哪个进程调用的,这个时候在函数中打印getCallingPid()的值,便可以找到调用此方法的进程id号。举个例子:
private void fun() { ... ... Log.d(TAG, "calling process id = " + Binder.getCallingPid()); ... ... }
Binder.getCallingPid()方法返回的是Binder IPC通信调用方的进程PID
还有一个类似的函数Binder.getCallingUid(),它返回的是Binder IPC通信调用方的进程UID
4. logcat
logcat命令是调试android系统最常用,也是最实用的一个命令,无论是APP还是framework。我们可以在代码的任何位置添加Log.d(java)或者ALOGD(cpp)输出我们想要的信息到logcat中。
最常使用的一条logcat命令是:
logcat -v threadtime -s xxx
这样打出来的log信息里会带有时间和进程ID, 更方便分析log。 加上-s选项,可以在需要的时候通过指定的TAG过滤掉不需的log。