调试Framework,让一切了然于胸

本文会详细介绍如何使用Android Studio调试Framework层中的Java代码,掌握了这一技巧,Android开发中任何Java层的问题我们都能够顺藤摸瓜,通过实际观察Framework层的运作来寻求解决方案。

为什么要调试Framework

对于Android开发已经入门的同学,免不了要接触到“View的绘制流程”、“Touch事件分发”这些知识点,我们可以通过他人的总结来了解这些知识点,然而更加彻底的学习方式是去阅读Android Framework层的相关源码。

有过Framework层源码阅读经验的同学都会知道,Framework层源码规模极其庞大,面对着这一大坨繁杂的源码,我们真的有必要面面俱到的阅读吗?实际上对于应用层开发人员来说,我们并不需要细致阅读Framework层的源码,毕竟我们不会去定制Framework。我们通常只需要关注Framework层代码逻辑的“主线”,也就是happy path,happy path指的就是通常情况下(不发生异常)执行的那一条代码路径。调试Framework,我们就能够迅速”拎出”Framework层中一段代码的happy path。

我们拿View的measure()来作为例子:

public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
  boolean optical = isLayoutModeOptical(this);
  if (optical != isLayoutModeOptical(mParent)) {
    // 代码块A
  }
  . . .
}

上面列出的代码在我们分析View的绘制流程时是一定会看到的。现在问题来了,代码块A会不会执行呢?显然,若我们不知道optical变量的含义是难以做出解答的,而如果我们在分析View的measure流程时每遇到一个地方不懂就去查资料,很可能会打击我们的积极性,也降低了阅读源码的效率。而且我们通常无需知道每句代码的含义,比如出于掌握自定义View的目的分析View的绘制流程,我们只需要抓住View绘制时通常情况下会执行的那条代码路径(happy path),就能够掌握View绘制过程的逻辑。

关于上面问题的答案,在掌握了调试Framework后,即使不了解optical变量究竟代表了什么,我们也能够知道。接下来让我们一起看看如何调试Framework。

如何调试Framework

这里介绍如何使用Android Studio调试Framework。在进行调试之前,除了Android Studio,我们还需要准备以下”原料”:

  • SDK源码,可通过SDK Manager下载;
  • Android真机或模拟器,其SDK版本需要与SDK源码版本一致。

如果要使用Android真机,我们需要注意的是要使用运行着Android原生系统的Android设备,比如Nexus系列。若使用第三方ROM,则可能会遇到代码“中断”在了空行的情况,这是因为SDK源码和设备中的代码不是同一份。因此务必要保证SDK源码版本与设备中SDK版本一致。

若我们想要调试的方法是SDK中导出的,那么只需要下载SDK源码就够了(无需显式导入,Android Studio会为我们自动关联)。而我们想要调试的代码不在SDK中,比如系统应用,我们就需要手动导入这部分的源码。

Android Studio中进行调试的方式有两种,一种是直接点击“ Run –> Debug ‘xxx’ “;另一种是在运行时点击” Run –> Attach debugger to Android process “。第一种会默认调试xxx应用进程,后者则可以选择调试哪个进程。若是我们想要跟踪View的绘制流程,那么通常只需要调试普通应用进程就足够了,因为View绘制的主要流程都是运行在普通应用进程中的。但是比如我们想要跟踪Activity的启动流程,那么仅对普通应用进程进行调试就行不通了,因为Activity启动时,大量代码逻辑都是在system_server进程中执行的,因此我们需要调试system_server进程。我们只能够调试”可调试进程“,模拟器的system_server进程是可调试的,这里使用了模拟器(Genymotion)进行演示。

简单演示

实际上,调试Framework与调试普通Android应用的流程是一样的,我们只需要在关键位置打断点,然后根据需要进行resume/step in/step over等操作。

这里我们以调试View.measure()方法为例,演示一下调试Framework的效果。这里我使用的模拟器软件是Genymotion,运行Android 5.1原生系统,Android Studio中关联的SDK源码版本也是Android 5.1。

现在我们来解答文章开始处提出的问题。首先在Android Studio中新建一个Hello World工程,然后View.measure()方法的首行代码处下一个断点,点击“ Run –> Debug ‘app’ “。代码运行起来后,我们会看到断在了View.measure()的首行代码处,如下图所示:

《调试Framework,让一切了然于胸》

然后我们设置如下两个断点,并让程序继续跑起来:

《调试Framework,让一切了然于胸》

可以看到程序断在了这里:

《调试Framework,让一切了然于胸》

这说明了if语句的then代码块并不会执行,也就是说measure()代码的happy path不包含开头处if语句的then代码块。

关注公众号,后台回复“模拟器”,获取Genymotion安装包。

《调试Framework,让一切了然于胸》

    原文作者:absfree
    原文地址: https://www.jianshu.com/p/7103b1ec91af
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞