Gradle性能检测

很多开发者从Eclipse迁移到Android Studio的一个最大的不习惯,就是Gradle的超慢编译速度。其实Gradle的编译速度很大程度上与项目的设置有关,要优化Gradle的编译速度,首先需要知道如何去检测Gradle的性能。

其实,Gradle编译工具本身就已经内置了一个性能分析工具——profile。通过Gradle编译的使用,只需要增加-profile参数即可打开该功能。执行以下脚本。

  1. gradle build profile

通过上面的脚本执行编译后,在根目录的Build目录下就会生成一个profile文件,如图4.34所示。

Gradle性能检测 - 图1 图4.34 profile文件

打开该文件,如图4.35所示。

Gradle性能检测 - 图2 图4.35 Gradle性能数据

这里显示了完整的Gradle编译过程的耗时,一般来说开发者最关心的是Task Execution的数据,如图4.36所示。

Gradle性能检测 - 图3 图4.36 gradle task编译耗时

这里排列了所有执行的Task的耗时数据。根据这些数据开发者可以进一步优化Gradle脚本。

举例来说,最耗时的Task就是Lint,而这个Task在一般Debug的时候是不需要的。因此可以先禁用这个Task来完成Lint的禁用。笔者在进行这一步骤的优化时,发现网上有很多类似的解决方案,其中被最多采用的是按以下代码进行Lint的禁用。

  1. tasks.whenTaskAdded { task ->
  2. if (task.name.contains("lint")) {
  3. task.enabled = false
  4. }
  5. }

这段代码看上去好像确实能够禁用掉Lint这一类的Task。但实际上,只要开发者尝试一下就会发现,无论是在根目录的build.gradle脚本中,还是在子module的build.gradle脚本中,这段脚本对于Lint都是无效的。原因在于Lint这个Task是Android Gradle Plugin中的Task,在执行工程的编译脚本时是无法获取到Lint。也就无法执行到whenTaskAdded函数,这也是这段脚本为何无效的原因。既然这样,那么怎么才能真正地禁用掉Lint呢?方法有两个,一个是通过Gradle的编译参数-x,执行以下指令。

  1. -x, --exclude-task Specify a task to be excluded from execution.
  2.  
  3. gradle build -x lint

其中-x参数表示排除掉一个Task,即Lint。通过这种方式可以实现禁止Lint的执行。另一种方式是在Gradle脚本中动态增加编译参数,脚本如下所示。

  1. project.gradle.startParameter.excludedTaskNames.add('lint')

这种方式与执行-x参数的含义是一样的。只不过一个是通过命令参数执行,另一个是通过动态脚本执行,它们的效果是一样的。

通过profile工具,再结合下面列举的禁用任一Task的方法,就可以通过编译耗时来有针对性地提高编译速度。

  1. aaptOptions {
  2. cruncherEnabled = false
  3. }

除了Task的耗时以外,AAPT检查也是一个耗时大户。在Debug版本中,笔者建议可以使用以下代码提高AAPT的速度。

Gradle性能检测 - 图4这种方式虽然提高了编译速度,但由于资源没有经过AAPT优化,可能会导致一些运行问题。所以最好只在Debug时采用这种方式,而在Release时一定不要使用。

相关的代码在Gradle DSL官方文档上也有详细介绍,通过这个方式可以极大地提高Gradle中AAPT的速度(仅在Debug版本中使用),官方文档地址如下所示。

http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.AaptOptions.html