记一次 Debug android 编译慢的过程

公司因为扩展业务,新建了一个 android 项目,但是这个安卓项目明明比我们的主项目代码量少那么多,但是编译时间却比我们主项目时间长非常多。让我每次编译的时候都思考人生。

项目基本情况

我们主项目是一个 80M 大小的App,dex 包都有 30M,更改一行代码的时间实际上只需要 30s 不到的时间,但是新项目 apk 大小都没有10M编译时间却要 一分多钟,有时候还需要 3分钟

调试方法

gradle 4.3 版本之后,gradle 提供了一个新的方法去扫描编译过程,就是
buildScan 功能,简单一点讲就是这个东西会把task运行过程很多东西记录下来,图形化展示这些数据,让你更好的发现问题所在。

怎么使用

只需要在运行的任务上加上 --scan即可,比如

./gradlew assembleDebug --scan 

运行之后会出现一个输入界面,如果是 yes 的话,就会上传到 gradle 的官方服务器上,然后生成一个链接,最后点击就能查看,比如下图这样

如果不想每次都敲个 yes 的话,可以在 gradle_home(没有改过的话就是 $user/.gradle) 的 init.d 目录上加入一个 buildscan.gradle 文件,文件内容如下

initscript {
    repositories {
        gradlePluginPortal()
    }

    dependencies {
        classpath 'com.gradle:build-scan-plugin:2.1'
    }
}

rootProject {
    apply plugin: com.gradle.scan.plugin.BuildScanPlugin

    buildScan {
        termsOfServiceUrl = 'https://gradle.com/terms-of-service'
        termsOfServiceAgree = 'yes'
    }
}

这样就不需要每次都敲个 yes 就能自动上传

问题发现

我给主项目和新项目各自生成了一份报告,在报告上我发现一个很有趣的地方新项目主要耗时 task 和旧项目的耗时 task 是完全不一样的

新项目报告

旧项目报告

一个是 compileDebugJavaWithJavac 一个是 mergeDexDebug,我只能知道新项目的执行逻辑是错的,但是并不知道为什么,直到我看到这里。

新项目

旧项目

两者用的 Android Gradle plugin 不一样,但是很奇怪的一点是,在根项目的 build.gradle 上我们写的版本号都是一样的,因为代码都是拷贝过来的。
报告是不会骗我们的,所以应该还有别的地方控制着这个版本,我想到了buildSrc这个地方
果然,在 buildSrcbuild.gradle 上,我们写了这样的代码


apply plugin: 'groovy'

dependencies {
    implementation 'com.android.tools.build:gradle:3.1.0'
}

当我把这个版本也改为 3.4.1的时候,编译速度终于正常了

结论

升级 Android Gradle Plugin 可以提高非常大的编译速度😆