提速 Android Gradle 构建

来源:互联网 发布:javascript .tagname 编辑:程序博客网 时间:2024/06/07 07:46

作者 | HangoX

地址 | http://www.jianshu.com/p/18a94011b3ad

声明 | 本文是 HangoX 原创,已获授权发布,未经原作者允许请勿转载



提速法则一览


以上优化方案基于 android gradle tools 3.0-alpha


关于 Santa Tracker Project 

https://github.com/google/santa-tracker-android


9 个模块,包括Wear

500 多个Java文件

1700 个XML 文件,3500张PNG

Multi-dex

没有 annotation processors

APK大小接近60MB


这个项目可以在 Google Github 帐号中找到


优化方案选择

避免使用遗留的 MultiDex


  • 遗留的 multidex 是指使用了 MultiDex 并且 minSDkVersion < 21

  • 遗留的 multidex 会导致构建的时候签名速度变慢

  • 使用 Android Studio 2.3+ IDE 构建的时候,会自动避免这样的状况


也就是说,使用点击 AS 运行的按钮,这个不需要配置。


关闭 multi-APK


multi-apk 是为了根据配置生成不同的APK,以达到减少APK体积大小的问题。但是这个配置没有必要在开发的时候开启。


关闭方法


设置监测到 flag 就关闭代码

android{
    if(project.hasProperty('devBuild')){
        splits.abi.enable = false
        splits.density.enable = false
    }
}


在AS设定中加入flag


或者使用 gradlew 构建


./gradlew app:assembleDebug -PdevBuild


包含最少的资源

如果你的 app 是包含多资源的,比如多语言的和多分辨率。但是在开发的时候,大部分时间都是只用一种资源,所以其他资源就会无用,导致拖慢构建速度。

以下是固定使用某种资源的办法

productFlavors{
    development{
        minSdkVersion 21
        resConfigs ("en","xxhdpi")
        ...
    }
}


关闭 png 压缩

png 在 android build tools 里面是默认开启的。这个功能可以使你构建更小的apk,但是在 debug 构建中,我们并不需要这个功能,所以,应该在 debug 构建的时候禁止。

禁止方法就是使用关闭 multi-APK 一样的标记

android{
        if(project.hasProperty('devBuild')){
            splits.abi.enable = false
            splits.density.enable = false
            aaptOptions.cruncherEnabled = false
        }
    }


添加标记的方法同关闭 multi-APK 的一样


当然你可以把图片转换到webp , 如果你的PNG已经压缩过的也可以完全关闭这个功能


使用 Instant Run


Instant Run 已经要求最低API 为21 ,各方面的兼容性都好了很多,推荐使用。

当然完整编译是需要更长的时间的


避免不注意的改变


栗子

def buildDateTime = new Date().format('yyMMddHHmm').toInteger()
android{
    defaultConfig{
        versionCode buildDateTime
        ...
    }
}


这个操作看起来很合理,每次构建的时候都可以获得唯一的versionCode,这样每次测试就能根据 versionCode 来告诉你问题所在。但是,对于 debug 构建来说,这不是一个好的设置。这个设置会导致 AndroidManifest 改变 , AndroidManifest 改变会导致增量编译的时间增加。



Crashlytics

Crashlytics 是个很好的开发工具,如果你使用得正确的话。Crashlytics 每次构建的时候都会生成唯一的ID,关掉这个 ID 可以加快构建速度。

apply plugin: 'io.fabric'
...

android{
    buildTypes{
        debug{
            ext.alwaysUpdateBuildId = false
        }
    }
}


不要使用动态版本号
android{
    dependencies{
        compile 'com.android.suport:appcompat-v7:+'        
    }
}


以上的依赖使用了动态版本号来设置使用最新的版本号。但是这样会导致 gradle 每 24 小时就要联网检查最新的版本,增加了构建的时间。同时,这样使用会导致你的构建不稳定,可能今天还能构建成功,但是明天就失败了


注意分配 Gradle 内存


在新建一个项目的时候,默认在 gradle.properties 中设置了 gradle 使用的内存为 1.5G,这可能是个好的值,也可能不是,取决你项目的大小,越大的项目需要越大的内存



开启 Gradle 缓存


这是 Gradle 3.5的新特性 ,和 2.3 build chache 是不一样的,可以接受任何系之前的构建,任何的地点的构建。

开启代码如下:


org.gradle.caching = true


使用 implementation 或者 api 代替 compile


假设你有如图这几个项目


app 依赖与 lib1,lib1 依赖于 lib2,但是,app 只使用了 lib1 提供的公共 api。如果使用 compile 关键字,当你更改 lib2 的时候,app,lib1 都要重新编译。但是,如果 app 是使用 implementtation 依赖 lib1 的时候,lib2 就算发生更改,app 也不需要重新编译。


所以我们在编写库的时候,如果库依赖的库不想曝光给使用者,建议使用 implementation,如果你想把自己使用的库曝光给使用者,请使用 api 关键字


额外提及

模块化好处


  • Gradle 可以平行的构建模块

  • 缺乏增量任务的一个变通方法

  • 多模块代表着多任务,多任务代表着可以平行执行

  • Some parallelism within a task is provided but limited(自己看吧,我也看不懂)


如何调试缓慢构建


Gradle 提供了工具去帮助知道哪里花了大部分时间


  • --dry-run

  • --info

  • --profile

  • Gradle profile


--dry-run


可以让你知道花费了多少时间在 configuration 上,10s以内是最好的,如果配置的时间过长,你的方法gradle 已经出了问题了。


使用方法:gradle yourtask --dry-run


--info


这个参数可以告诉你,当前任务执行的详细信息,包括在执行什么,还有为什么执行。


使用方法:gradle yourtask --info


--profile


这个参数会在 you-project/build/reports/profile、 中生成一个html文件,详细告诉你哪个任务花了多少时间,是个非常有用的debug工具


使用方法:gradle build --profile


Gradle Profiler


Gradle Profiler https://github.com/gradle/gradle-profiler 是 Gradle 官方用于自动收集 Gradle 构建的分析和基准测试信息的工具。具体的使用办法在 github 上有,以后有必要再出个专题吧。这个工具是当上面的办法都无效的时候才推荐使用的。



与之相关

1 Gradle 的高级技巧

2 Android 解锁 Gradle 依赖新姿势


赞助商

优秀人才不缺工作机会,只缺适合自己的好机会。但是他们往往没有精力从海量机会中找到最适合的那个。100offer 会对平台上的人才和企业进行严格筛选,让「最好的人才」和「最好的公司」相遇。扫描下方二维码,注册100offer,谈谈你对下一份工作的期待。一周内,收到 5-10 个满足你要求的好机会!

原创粉丝点击