技术背景:随着一次次的产品迭代,项目变得越大越大,同时编译项目也越来越耗时,原来调侃点击AS的run后可以先去泡杯咖啡。现在要泡两杯咖啡才能编译好 dog脸
采取的措施:网上看了些文章,比如这个
有很多措施可以瘦身APK,当然瘦身后编译也会快起来。但大多数措施还是比较耗时或者复杂,或者有兼容性的顾虑。我就先采用些简单的方法,并且记录下具体步骤,而且主要目的是提高编译速度。
lint unused resources
可以使用AS的Analyze功能中的lint来找出多余无用的资源文件,然而我居然搜出几百个文件,当然不能一个一个删。于是问Google,找到了工具android-resource-remover 也就是帮你删掉lint出来的unused的资源文件。
用法:
- step 1:装pip打开命令行,敲
**sudo easy_install pip **- step 2:装好pip后装android-resource-remover:敲命令
pip install android-resource-remover- step 3: 在命名行中进入到你APP的项目的路径,然后敲
./gradlew -v
此时有两种结果,或者是显示版本号,或者是点点点开始下载gradle。如果是下载,那就等下载好再进行下面一步- step 4: 同样在APP项目目录上,敲
**./gradlew lint **
表示开始lint 这个过程需要几分钟,请耐心等待。
tip:我执行这一步的时候报错,然后按照提示在项目所有的gradle文件中加入abortOnError false, 表示lint出错误也不停止lint
- step 5:敲
./gradlew clean build :android-resource-remover --xml your lint-results.xml location
其中your lint-results.xml location是声明第四步中生成的lint扫描结果xml文件的位置,所以你要替换成具体的位置。默认文件名是lint-results.xml,除非你在gradle的lintOptions里配置了。具体在哪,mac里只要在finder中一搜就能知道。
这一步也需要几分钟。
就此,删除工作完成。也可以多删除几次,清理的更彻底。想了解更多请访问主页
tip:主页上第四步和第五步合成了一步: ./gradlew clean build :lint && android-resource-remover --xml build/outputs/lint-results.xml 但我执行时报错,Task "lint" not found. 其实不是没有lint task,只是在执行lint时报错了,所以先执行./gradlew lint ,如果有报错还可以按照提示解决。
优化库
只引入用到的子库,去掉重复功能的库,自己裁剪用到的lib库等,通过减小项目的size来加快build。
Gradle 配置:
AS部分
- 设置offline work
[图片上传失败...(image-4ec425-1514954387542)]
- 设置gradle版本2.4以上
[图片上传失败...(image-1e81a3-1514954387543)]
file configuration部分
- 全局设置 对所有project有效(有几个设置项也能通过AS设置,这里就不另外介绍了)
文件位置: /Users/apple/.gradle/gradle.properties
这个是隐藏文件夹,所以需要先用命令
defaults write com.apple.finder AppleShowAllFiles -boolean true ; killall Finder
显示隐藏文件夹。如果没有gradle.properties 文件的话就新建一个。
写入以下内容:
org.gradle.daemon=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true
org.gradle.configureondemand=true
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
其实我最后一行是
org.gradle.jvmargs=-Xmx6144m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
因为我的电脑内存有8G内存,所以可以拿出6G,也就是6114M供build用
你也可以在项目的gradle-wrapper.properties文件中覆写相关参数
以上参数的介绍,注意事项
- gradle script部分
在开发阶段时,productFlavors中只保留一个flavor,如果有几个flavor,build阶段就会assemble多个,纯属浪费。并且添加如下两个参数:
productFlavors { xiaomi { // 这个参数只在开发阶段调整为真机的版本,越高越好 // utilizes minSDKVersion = 21 to allow the Android gradle plugin // to pre-dex each module and produce an APK that can be tested on //http://blog.zongwu233.com/the-touble-of-multidex/ minSdkVersion 23 useJack = true }
第一个参数我设置成23,这样build时就不会执行兼容低版本相关的task,比如dex method相关。
第二个参数是一个experimental阶段的功能,能够加快build,不过与我项目中的android annotation和com.neenbedankt.gradle.plugins冲突,就没用。
这两个参数的注意事项
还有几个重要的参数,设置如下:
android {
// 其它设置
dexOptions {
incremental true
javaMaxHeapSize "4g"
preDexLibraries = true
}
}
这个参数的介绍
(更新:如果使用gradle 2.2.0及以上,build时会弹出
Warning:Theandroid.dexOptions.incremental
property is deprecated and it has no effect on the build process.,即不需要设置incremental true这个选项了)- 跳过不必要的task,比如test相关
看看你有哪些task
在项目路径执行 ./gradlew assembleXiaomiDebug --profile
assembleXiaomiDebug表示组装生成XiaomiDebug的APK。XiaomiDebug表示flavor是xiaomi,debug版本,你要确认这个名字可以AS右侧点击Gradle图标,在task列表中找。
--profile表示生成report文件。
执行完毕后你就可以在项目路径搜索profile文件下,在此文件夹下会有类似profile-2016-03-26-14-44-17.html的文件,打开你就可以看到task执行的报告了,效果如下
[图片上传失败...(image-a70197-1514954387543)]
不仅可以看哪些是耗时的task,也可以对比优化后build快了多少。
跳过耗时的task示例:
tasks.whenTaskAdded { task ->
if (task.name.startsWith(":zxing:") || task.name.startsWith(":share-lib:")) {
task.enabled = false
}
}
本文有参考秋百万大神的文章
通过优化后,如果项目没改动,debug的build只需7秒,有改动的话一分多钟,比原来的4分钟要快很多了。
然后我发现build完成后,upload到真机上,也就是
DEVICE SHELL COMMAND: pm install -r 命令执行了大概一分钟,install什么时候这么慢了,上网查了下有人说是高版本的安卓是把一些事务放到手机上执行了,所以慢了。如有大神了解相关原理或优化的,请交流下。
补充
图片压缩
图片格式选择请参照下图
如图所示在格式选择上先考虑VD或者shape,然后是WebP,然后构图简单或者需要透明度的图可以选择PNG,不然选择JPG
原始图片来自谷歌IO
VD指的是VectorDrawable
在安卓4.0以上支持webp格式,但无损和带透明度的webp格式要求4.2.1以上。可以使用AS自带的转换快捷方式。即在AS中选中图片->右键->Convert to WebP,建议采用无损压缩,防止图片模糊。
而isparta不仅转换WebP,而且也能压缩PNG,如有需求,自行下载。
PNG压缩的一个方法是:减少颜色数(Reduce Colors),比如你要压缩的图片顶多只有8种颜色,你就可以选择8后压缩,如图: