你可以看到这里的第一列,代表的是当前的用户,这里有system root和u0_axx,不同的用户有不同的权限。我们当前关注的是第二列和第三列,第二列代表的是PID,也就是进程ID;第三列代表的是PPID,也就是父进程ID。
你发现我这里框住的都是同一个父进程,那么我们来找下这个323进程,看看它到底是谁。
root 323 1 1089040 127540 poll_schedule_timeout f16fcbc9 S zygote
这个名字在学习Android系统的时候,总被反复提及,因为它是我们Android世界的孵化器,每一个上层应用的创建,都是通过Zygote调用fork创建的子进程,而子进程可以快速继承父进程已经加载的资源库,这里主要指的是应用所需的JAR包,比如/system/framework/framework.jar,因为我们应用所需的基础控件都在这里,像View、TextView、ImageView。
接下来我来讲解下一个调试,也就是对TextView的调试(其他Button调试方式一样)。如前面所说,这个代码被编译到/system/framework/framework.jar,那么我们通过ps命令和cat /proc/pid/maps命令在Zygote中找到它,同时它能够被每一个由Zygote创建的子进程找到,比如我们当前要调试Gallery的主界面TextView。
我们验证下,使用ps -A |grep gallery3d查到Gallery对应的进程PID,使用cat /proc/pid/maps |grep framework.jar看到如下信息:
efcd5000-efcd6000 r--s 00000000 08:06 684 /system/framework/framework.jar
这说明我们要调试的应用进程在内存映射中确实存在,那么我们就需要在gallery3d进程中下断点了。
下来我们建立调试环境:
- 打开Genymotion,选择下载好Android 9.0的镜像文件,启动模拟器,然后在桌面上启动Gallery图库应用。
- 找到模拟器对应的TextView.java代码。
- 打开Android Studio,File -> New -> New Project然后直接Next直到完成就行。
- 新建一个包名,从TextView.java文件中找到它的包名,这里为android.widget,然后把TextView.java放到里面即可。
- 在TextView.java的onDraw方法上面设置断点,然后找到菜单的Run -> Attach debugger to Android process勾选Show all process,选中com.android.gallery3d进程(我们已知这个主界面有TextView控件)确定。
然后我们点击下这个界面左上角的菜单,随便选择一个点击,发现断点已生效,具体如下图所示。
然后我们可以使用界面上的调试按钮(或者快捷键)进行调试代码。
今天我讲解了如何调试Framework中的系统服务进程的AMS服务线程,其他PMS、WMS的调试方法跟AMS一样。并且我也讲解了如何调试一个应用里面的TextView控件,其他的比如Button、ImageView调试方法跟TextView也是一样的。
通过今天的学习,我希望能够给你一个学习系统框架最便捷的路径。在解决系统问题的时候,你可以方便的使用调试分析,从而快速定位、修复问题。
那么,你是否已经跃跃欲试,准备调试一下自己的应用呢?提出一个问题,我们调试Gallery应用的TextView时候,前提是让这个应用先运行起来,如果我们想调试从点击桌面Gallery图标到Gallery主界面绘制出来的过程,该如何调试呢?
我们是否能够调试市面上发行的三方应用呢?比如微信,支付宝的某个界面的TextView控件?
再深入一下,如果我们想研究市面一款应用的内部实现,需要反编译分析代码,我们能否调试反编译出来的Smali代码呢?
推荐阅读: