调试Framework,让一切了然于胸

作者: absfree | 来源:发表于2016-12-09 16:56 被阅读1332次

    本文会详细介绍如何使用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()的首行代码处,如下图所示:


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



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



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

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

    相关文章

      网友评论

        本文标题:调试Framework,让一切了然于胸

        本文链接:https://www.haomeiwen.com/subject/hdhemttx.html