这一节会介绍之前没提到的构建技巧和提示,包括
ProGuard是一个java工具,不仅可以收缩代码,还能优化,混淆代码和编译阶段验证代码,他会查找所有并删除未使用的代码,也会重命名类和属性,让app难以被反编译。android插件有个属性minifyEnabled在build.gradle中,就是设置是否开启ProGuard功能。
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile
('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
如果设置为true,progrardRelease task就会在构建过程调用ProGuard。
最好设置后重新测试下app,因为他有可能会造成需要的代码丢失,为了解决这个问题,可以定义ProGuard规则去排除一些类避免被移除或者混淆,proguardFiles属性就是定义规则文件的。比如,保留一个类,在规则文件中这么写
-keep public class
getDefaultProguardFile(‘proguard-android.txt’)方法从proguard-android.txt文件中获取默认ProGuard设置,这个文件来自Android SDK的tools/proguard文件夹。proguard-rules.pro文件会被AS默认添加到新的module中,可以在这里添加新的规则,每个项目的规则都不太一样,具体要看引入的库和自己写的代码,学习ProGuard和ProGuard rules,参见文件
除了压缩java代码,还有一个好办法是压缩资源文件
gradle可以在构建阶段去掉未使用的资源,这在你有很多老的资源忘记移除,或者有一个库有很多资源,但是你只想用很少一部分,就可以开启资源压缩。有2个方法,自动的和手动的
android {
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
}
}
}
最简单的就是配置shrinkResources,就可以自动压缩,但是最好把minifyEnabled也开启,因为资源压缩需要依靠哪些资源未被代码引用才去移除,如果没有压缩代码,可能哪些无用的代码在引用资源,导致本来无用资源也没被移除
如果想明确的看压缩后小了多少,可以运行shrinkReleaseResources task,将打印出包大小减少了多少
:app:shrinkReleaseResources
Removed unused resources: Binary resource data reduced from 433KB
to 354KB: Removed 18%
如果想看到详细的哪些资源被移除,添加–info
$ gradle clean assembleRelease --info
他将打印出关于哪些资源未被加入到apk的额外信息
自动压缩有个问题就是,它可能会移除过多的资源,特别是动态使用的可能会被意外移除,为了避免这个情况,可以定义哪些资源需要保留在keep.xml中,这个文件放在res/raw/下去创建,keep.xml的简单例子
1.2.2 手动压缩(Manual shrinking)
平和一点的方式是移除某些语言文件或者某些密度的图片文件。一些库,比如Google Play Services,包含了大量语言文件,我们的app可能只需要1到2种语言,这样就很浪费,可以使用resConfigs属性配置要保留的资源,剩余的会被扔掉。
如果你只想要English,Danish和Dutch
android {
defaultConfig {
resConfigs "en", "da", "nl"
}
}
也可以定义密度
android {
defaultConfig {
resConfigs "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"
}
}
你甚至可以组合配置语言和密度,每一种资源都可以通过这个属性进行限制
NOTE: 在配置中写的会保留,其他的都会被抛弃(不会被打包到apk)
很多开发者抱怨编译时间太长。由于gradle整个生命周期有3个阶段,每次运行task都要经历,这使得整个过程都可配置,但是也变得很慢。幸运的是,有一些方法去提高构建速度
一个微调构建速度的方法是改变一些默认设置,在第5章提到了并行构建,但还有更多设置我们可以调整
开启并行构建,在gradle.properties文件配置
org.gradle.parallel=true
另一个是开启Gradle daemon,这会开启一个后台进程在你第一次运行构建程序,任何后面的子构建都会复用整个进程,避免了重启的开销。这个进程在运行gradle时一直存活,空闲3小时后才挂掉,在你短时间多次使用gradle时候效果很好,同样在gradle.properties
org.gradle.daemon=true
在AS中daemon默认开启,意味着在IDE中第一次构建后,后面的构建都会快一点,如果是命令行构建就不行,除非定义了属性在文件中,像上面那样
提升自己的编译速度,可以微调虚拟机参数,比如,jvmargs属性,可以设定不同值的内存大小给jvm。-Xms设置初始大小,-Xmx指定最大内存,同样在gradle.properties配置
//大小单位k(kb) m(mb) g(gb)
org.gradle.jvmargs=-Xms256m -Xmx1024m
要看自己电脑的能力设置大小
最后一个能影响构建速度的可配置属性是org.gradle.configureondemand,这个属性在你的项目有很多module时候很有用,他会尝试限制在配置阶段消耗的时间,会跳过正在执行的task不需要的module,如果设置为true,gradle会尝试在配置阶段前计算出哪些modules有配置变化,哪些没有。如果项目只有一个app和一个库,这个属性就没啥用了
如果想在所有项目应用这些配置,可以在.gradle文件夹下创建gradle.properties文件,.gradle一般在c盘用户目录下(windows系统)
在as中也可以配置这些属性,在settings中的compiler选项
如果想知道哪些部分降低了构建速度,可以在执行任何task时候后面加上–profile标志,这样会在module的build/reports/profile下面生成html形式的报告,告诉你哪些过程时最消耗时间的,比如
gradle clean --profile
2.4 Jack和Jill
如果想体验实验性的工具,可以开启Jack和Jill提升构建速度,Jack是益虫新的构建工具链,可以把java文件直接转换成dex格式,他有自己的.jack库来打包和压缩。Jill是一个把.aar和.jar文件转换成.jack库的工具,他们还出一实验性阶段,但是可以提升构建速度和简化构建流程,但是不建议在正式项目使用,为了开启这个,需要构建工具版本21.1.1或更高
android {
buildToolsRevision '22.0.1'
defaultConfig {
useJack = true
}
}
也可以指定他俩在某些build type或者product flavor上开启,这个方式,我们可以同时继续使用常规构建工具
android {
productFlavors {
regular {
useJack = false
}
experimental {
useJack = true
}
}
}
设置useJack为true,压缩和混淆就不再通过ProGuard执行了。但是仍然可以使用ProGuard规则语法指定规则和例外(也就是资源保留)
在运行发布构建时候,静态代码分析工具Lint就会执行,标记出潜在的布局或代码错误,某些时候,这样会阻塞构建过程,忽略Lint错误可以避免终止构建,但是这只应该用在一些临时情况,不然构建虽然完了,但是有可能有些错误存在,配置如下
android {
lintOptions {
abortOnError false
}
}