在 Android Studio 里使用构建分析器提升构建性能

在 Android Studio 里使用构建分析器提升构建性能

作为 Android 开发者工具团队的成员,我和团队成员们每天都抱着将 Android 打造成最好的移动开发者平台的想法来制作各种工具。这意味着我们会构建一些帮助您开发应用的工具,让您专注于编写应用。

我们知道超长的构建既浪费时间也会打断开发流程,并且会让开发者十分沮丧。Android Studio 用户平均每周构建 65 次,所以即便每次构建只慢 10 秒钟也会浪费每个开发者一年大约 9 个小时的时间。尽管如此,如我们在稍早的文章《在 Android Studio 中优化构建速度》提到的,大约有 60% 的 Android 开发者不会去做构建分析。再加上不断增长的项目复杂度,最终导致了所有使用 Android Studio 的项目构建时间不断增长,也严重影响了开发效率。

为了解决这个问题,我们制作了构建分析器。这个工具可以帮助所有开发者理解影响他们项目构建时间的因素,以及如何减少这些因素的影响。

充分使用构建分析器 (Build Analyzer) 提供的功能

每次构建应用,Android Studio 都会生成一个构建分析器报告。为了看到这个报告,请确保您按照如下步骤操作:

  1. 升级 Android Gradle Plugin 到 4.0.0 或更高版本。
  2. 构建或者重新构建您的工程。
  3. 通过选择 View > Tool Windows > Build 菜单来访问构建分析器,然后点击 Build Analyzer 标签。

Santa Tracker 应用是 Google 开发的一个教程性质的开源应用,为了这篇文章,我们将 clean build 这个应用,并和大家一起理解生成的构建分析报告。

打开构建分析器,您会看到 Overview 页面。这个页面展示了一些基本信息以及跳转到各个详情页的链接。如下图所示,我们立即就会发现,这个构建的耗时主要来自于任务执行而不是构建的配置。

为了了解更多,让我们来继续深入分析构建分析器所提供的两个数据集。它们分别是 Tasks (任务)Warnings (警告)。您既可以通过 Common views into this build 下的链接来访问,也可以通过左上角当前显示 "Overview" 的下拉菜单来切换。

任务

这些任务决定了刚刚观察到的构建时间,其中有的是因为输入、输出的依赖关系,而其他的则是由于并行构建的约束。除此之外的任务,可以并行运行并且不会对构建时间有影响。查看这个面板可以告诉我们构建应用的哪个步骤是最耗时的。

当展开列表来查看这些任务的时候,每个任务会根据来源显示为不同的颜色。来自 Project Customizations 的任务是由您项目的本地自定义的,也是最容易被修改的。被标示为 Android/Java/Kotlin Plugins 的任务来自于核心插件。而 Other Binary Plugins 的任务要么是来自您团队成员编写的二进制插件,或者是来自第三方制作的二进制插件。

默认情况下这些任务会以展开列表的形式显示,但是也可以使用 Group by plugin 选项来按照任务来源的插件分组。这样分组会将您项目中的每个插件显示为一个节点,而不是按照单个任务来显示。

这样分组会让我可以观察到,我项目构建的大部分时间是在执行来自核心插件的任务,比如 Kotlin 或者 Android Gradle 的插件。这并不意外,尤其是在对于像 Santa Tracker 一样的项目运行全量构建的时候。而在运行增量构建的时候,核心插件的任务通常会耗费相对较少的时间,这样会便于我们发现其他插件对于构建时间的影响。

当我们需要比较添加或者升级某个插件对于构建时间影响的时候,这个插件视图格外有用,因为它会帮助您权衡更改的好处和它们对于构建时间带来的影响。无论什么时候,对于更改的谨慎是防止我们不断地增加项目构建时间的最好办法,也就能避免其影响我们的开发效率。

警告

这个视图可以让您看到该构建生成的所有警告,其中也包括了那些并不会影响构建时间任务的警告。

每个警告信息都会包含其产生的原因和推荐的解决办法,以及如果适用的话,也会包含生成该警告的任务的详细信息。如果该警告不是来自您的团队成员的插件,您可以使用 Generate report功能来向该任务或插件的作者进行反馈。

如上图显示,在使用构建分析器分析我们之前提到的 Santa Tracker 项目时,生成了一个 Task Setup 警告。这个问题看起来是由于输出目录冲突造成的,所以我们可以修改 generateExtraResources 任务和 mergeDebugResources 任务其中之一的输出文件路径。mergeDebugResources 任务来自于 android 基础插件,并且不能在本地修改。generateExtraResources 任务被标示为 project customization 且该任务是我的团队制作的。基于此我决定修改 generateExtraResources 任务。

另外需要注意的是,上面的报告来自于全量构建,而增量构建的报告之间会不太一致,但却可能更真实地反映您平时的开发流程。所以在使用构建分析器的时候,请确保您使用了全量构建和增量构建。想要了解更多关于构建分析器的内容,请查阅 Android 开发者官方文档|排查构建性能问题

构建分析器如何工作

每当您使用 Android Studio 构建您的项目,构建分析器会使用 Gradle Tooling APIAndroid Gradle Plugin 在本地收集数据。Tooling API 会被用来绑定 ProgressListener,它会提供关于项目的配置、任务执行、注解处理器等信息。Android Gradle 插件会提供更多的其他信息,包括任务名称和任务类名的映射,以及任务的配置信息。

当您的构建结束的时候,构建分析器会将这些信息输入一系列的分析器,每个分析器会找到并报告特定的问题。举个例子,有一个分析器会检查那些被设置为每次构建都需要执行的任务,因为这些任务会阻碍增量构建节省时间,而这会严重影响构建速度。

那这个分析器是如何发现那些每次都执行的任务呢?当一个 Gradle 任务的输入或输出对比上一次构建没有变化的时候,这个任务被认为是 up-to-date 的。当一个任务是 up-to-date,Gradle 会跳过执行该任务并复用这个任务以前的输出,而不是浪费时间重新执行它。如果一个任务没有声明输入或输出,那它永远不会认定为 up-to-date。这个分析器依靠 Gradle Tooling API 提供的任务输出信息找到所有有问题的任务,它们要么是没有声明任何输出,要么是替换 up-to-date 为 false。通过这个方法,这个分析器可以找到所有永远不会 up-to-date 的任务,而这些任务每一次构建都会运行。我们希望可以利用这个分析器帮助您快速地定位问题,并开始充分利用增量构建。

目前除了这个可以识别每次构建都运行的任务的分析器,还有其他两个分析器。其中一个可以识别 非增量的注解处理器,另外一个可以识别任务之间替换彼此的输出。未来我们计划继续发布各种分析器,来帮助您快速地发现常见问题以及掌握关于使用 Gradle 的最佳实践。

后续行动

如果构建分析器报告了一个来自第三方插件任务的警告,您可以考虑向插件的原作者提交 bug 报告。类似的问题有可能不会被立即解决,但是这会帮助整个生态变得更好。如果您认为这个问题来自构建分析器本身,请通过我们的 issue tracker 来让我们知道。

如果您有兴趣深入理解您的项目构建,请尝试用 Gradle Scan 来获取更多额外的信息。此外,使用 Gradle 的 Build Cache 也可能减少您的构建时间。

随着这个工具逐渐成熟,我们希望能够扩展分析器套件来识别更多的警告。我们热切地希望了解人们是如何使用这个工具,同时我们也会继续改进跳转浏览、图形化和其他相关组件。如果您有任何反馈,尤其是那些您在自己的项目构建中发现的,但是没有被我们的分析器捕获到的问题,请告知我们。

版权声明

禁止一切形式的转载-禁止商用-禁止衍生 申请授权

脉脉不得语
脉脉不得语
Zhengzhou Website
Android Developer | https://androiddevtools.cn and https://androidweekly.io WebMaster | GDG Zhengzhou Funder & Ex Organizer | http://Toast.show(∞) Podcast Host

你已经成功订阅到 Android 开发技术周报
太棒了!接下来,完成检验以获得全部访问权限 Android 开发技术周报
欢迎回来!你已经成功登录了。
Unable to sign you in. Please try again.
成功!您的帐户已完全激活,您现在可以访问所有内容。
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.