纳尼?个人Gradle build编译只要1s

为了不被Diss,先声明了,本文不算原创,只是对几篇Gradle编译提速的文章进行了: 搬运整理细化和补漏,文尾已列出相关的参考文献!先上个图舒服下:html

(PS:这是直接新建的项目经过各类折腾后编译的时间,笔者公司的项目折腾完耗时5s左右, 可是由于兼容要改的东西多,升级gradle等操做并没弄,不过也是效果明显,真的能够试试~)java

大部分的Android开发仔吐槽的最多的基本都是等Gradle编译。android

编译能够说是平常操做最频繁的,在调UI,调试改Bug时候达到一个峰值,每改点东西, 就build一下。能够说是至关可怕,咱们来粗略的算一笔帐:浏览器

假设编译一次要3分钟,一天编译40次缓存

  • 天天花费:2小时等待编译
  • 一周花费:14小时等待编译
  • 一个月花费:60小时等待编译 => 2.5天

每月花2.5天是在等待Gradle编译,多呆哦,因此,让Gradle编译提速,显得格外重要, 本节就从方方面面说下减小这个等待的时间吧。bash


1.升级下你的电脑配置

大部分的Gradle编译卡和慢,都是由于电脑配置的缘由,我的感受关键基本配置以下:app

  • CPU:i5系列就够了
  • 内存:重要!至少要8G,有条件建议上16G
  • 硬盘:重要!必须是SSD固态硬盘,穷一点的上128G,稍微宽裕点上256

其余好比显卡啊啥的没什么太大影响,配置确定是越高越好,在本身的经济承受范围之内便可。jvm


2.调整AS的内存分配

电脑配置差很少了,接下来就要调整下AS的可以使用内存,打开AS在右下角能够看到使用内存和分配内存,如图所示:maven

若是你的AS里没有这个图的话,能够依次点击菜单栏的:「File」->「Settings」->「Appearance % Behavior」-> 「Appearance」-> 找到如图所示的「Show memory indicator」勾选,而后点击OK,就能够在状态栏看到内存分配信息了。ide

接着咱们来修改AS的内存分配,来到AS的安装目录下,进入bin目录,找到:

用文本编辑类软件打开对应文件,内容以下:

-Xms256m
-Xmx1280m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djna.nosys=true
-Djna.boot.library.path=

-da

复制代码

接着咱们修改下前三项,改为更大的值:

-Xms512m    //JVM启动的起始堆内存,堆内存是分配给对象的内存
-Xmx2560m   //Java虚拟机启动时的参数,用于限制最大堆内存
-XX:ReservedCodeCacheSize=480m  //JIT java compiler在compile的时候的最大代码缓存
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djna.nosys=true
-Djna.boot.library.path=
复制代码

修改完后保存,而后回到AS中,依次点击菜单栏:「File」->「Ivalidate Caches/Restart...」,点击后出现如图对话框,点击「Ivalidate Caches/Restart...」。

而后等待AS重启便可。而后右下角能够看到可用内存已经发生了改变,AS明显打开流畅多了。


3.增长Gradle的堆大小并启用dex-in-process

Dex-in-process容许你dex和gradle构建在同一个进程进行,以此加快增量构建和干净构建的速度。 要使用dex-in-process很是简单:确保 grale 进程有足够的内存分配给 dex 步骤来完成整个操做。 建议的公式:

Gradle memory >= Dex memory + 1Gb !
复制代码

就是分配给gradle的内存比dex的内存多1g,dex进程内存设置在开发module的 build.gradle里面控制。添加以下内容:

除此以外,dexOptions中还能够添加下述配置:

//使用增量模式构建 
incremental true 

//是否支持大工程模式 
jumboMode = true 

//预编译 
preDexLibraries = true 

//线程数 
threadCount = 8 
复制代码

配置完dex,接着要配置gradle,打开「gradle.properties」修改org.gradle.jvmargs 的大小,按照公式,多1g,因此这里配置成2g:

org.gradle.jvmargs=-Xmx2g
复制代码

除此以外设置下JVM最大容许分配的非堆内存,以及堆内存移除时输出堆的内存快照。

org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=0.5g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
复制代码

接着能够再Terminal中中键入gradlew clean build来看看构建的速度是否加快了。 通常dex设置为1-2G,gradle设置为2-4G就能够了,分配更多的内存并不会使构建加快多少!


4.其余gradle.properties配置

除了配置给gradle分配的内存外,还能够经过添加下述配置使得构建加快:

#开启守护线程
org.gradle.daemon=true
    
#开启并行编译任务
org.gradle.parallel=true
    
#开启缓存
android.enableBuildCache=true
复制代码

另外,你还能够在下述目录中建立一个gradle.properties文件,全局生效,就不用每一个项目都另外配置了, 固然你喜欢仍是能够在项目中建立这个文件。


5.配置依赖包下载地址

就是使用阿国内阿里云的依赖下载地址替换Google依赖包下载地址,打开Project级别的build.gradle文件,添加阿里云的地址:

repositories {
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
    ...
}

allprojects {
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
        ...
    }
}    
复制代码

6.离线编译

若是你的项目比较稳定,没有什么新的依赖(第三方库引用),可使用这种方法来提高编译速度。 依次点击菜单栏「Setting」->「Build」-> 「Gradle」,找到如图的「Offline work」勾选,点击OK便可。

也能够不配置,在命令行编译的时候加上**--offline**,好比:

gradlew build --offline
复制代码

7.使用静态依赖项版本

在引用依赖库的时候,尽可能避免使用+这种动态版本号,而尽可能使用静态编码编码版本号, 若是用动态版本号,每次编译的时候Gradle会去检查是否有更新,好比:

# 动态版本号
com.android.tools.build:gradle:3.2.+

# 静态版本号
com.android.tools.build:gradle:3.2.1
复制代码

8.禁用耗时但在Debug时不须要的Task

你能够经过下述两种方式,查看编译的时候都执行了哪些Task,以及他们的耗时。

方法一:经过gradlew --profile

编译命令后加上--profile,好比 gradlew build --profile,会输出打包过程的profile report

接着按照给出的路径找到对应的html文件,用浏览器打开,点击「Task Execution

而后就能够看到全部执行的Task和所需的耗时。除此以外,还能够

方法二:使用build scan(构建审视)

Gradle 官方推出的一个可视化诊断工具,官网地址:gradle.com/build-scans…,不一样的Gradle版本对应的 build-scan-plugin的版本也不一样,能够在官网查看对应的版本号:Gradle Enterprise version compatibility, 好比个人4.6对应最低版本的build scan工具的版本号为:1.8。接着在项目级别的build.gradle文件中添加相关代码:

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "com.gradle:build-scan-plugin:1.8"
  }
}

apply plugin: "com.gradle.build-scan"
复制代码

接着命令键入:gradlew build --scan编译完会问你是否Push到gradle.com,键入: yes便可。

若是不想每次都键入yes,在build.gradle中添加下述代码:

buildScan {                     
    licenseAgreementUrl = 'https://gradle.com/terms-of-service'
    licenseAgree = 'yes'
}
复制代码

接着点击打开连接,会让你输入一个接收报告的邮箱:

接着会受到一个邮件,点开就能看到本次编译的相关信息了,好比这里看到占较多编译时间的Task是lint:

行吧,从上面的两个例子咱们能够明显的看到lint耗时很多,而Lint在Debug阶段并不须要,咱们能够下述三种方式来禁用:

  • 1.经过Grale编译参数禁用
gradlew build -x lint -x lintVitalRelease
复制代码
  • 2.Gradle脚本中动态添加编译参数

项目级别的build.gradle中buildScript添加下述代码:

gradle.startParameter.excludedTaskNames.add('lint')
gradle.startParameter.excludedTaskNames.add('lintVitalRelease')
复制代码
  • 3.永久禁用lint

在模块级别的build.gradle中的

apply plugin: 'com.android.application'
复制代码

前加上下述代码:

tasks.whenTaskAdded { task ->
    if (task.name.contains("lint") || task.name.contains("lintVitalRelease")) {
        task.enabled = false
    }
}
复制代码

9.一些其余的小点

① 减小本地库依赖

Gradle在编译时会执行大量Task,生成不少中间文件,会致使磁盘IO拥堵,形成编译变慢, 能够减小本地库依赖,多使用aar进行依赖。

② 修改minSdkVersion>=21

若是你不须要兼容低版本的设备的话,能够把minSdkVersion改成21以上(Android 5.0),使用ART,在Build时只作class to dex, 而不作mergeing dex,一样会节省一点的时间。

③ 使用implementation替代compile

注:Gradle版本需大于3.4,示例以下:

compile 'com.android.support:appcompat-v7:28.0.0'
# 改成:
implementation 'com.android.support:appcompat-v7:28.0.0'
复制代码

一样的替换还有:

  • testCompile -> testImplementation
  • androidTestCompile -> androidTestImplementation
  • provided -> compileOnly

④ 将图像转换成 WebP

有效减小图片文件大小,没必要执行构建时压缩,从而加快构建速度,若是你的APP用到大量图片资源的话,效果明显。

⑤ 停用 PNG 处理

若是不想把图片替换成WebP,可在每次构建应用时停用自动图像压缩的方式加快构建速度。模块级别build.gradle添加下述代码:

android {
  ...
  aaptOptions {
    cruncherEnabled false
  }
}
复制代码

⑥ 按需编译而不是无脑build

直接**gradlew build和执行gradlew assemble** 会同时编译生成Debug和Release的包,在调试阶段其实 咱们可使用:

gradlew assembleDebug
复制代码

来只编译Debug版本的包,除此以外还能够用另外一个命令编译完直接安装到设备上:

gradlew installDebug
复制代码

同理对应Release的命令为:

gradlew assembleRelease
gradlew installRelease
复制代码

行吧,关于Gradle编译提速大概就这些,有补充的欢迎在评论区留言,谢谢~


参考文献


Join in

欢迎你们加入开发交流群一块儿讨论学习,能够添加下述的机器人小号 RobotPig,发送『菜单』 输入对应的提示,加入对应的开发群(Android或Python),或者在公众号『抠腚男孩』中发送加群~
半自动拉人,会有延时,请谅解~

机器人小号