Gradle的使用技巧
定义一些统一的编译变量
当我们在一个AS的Project里面,有挺多的module和library的时候,我们需要统一各个模块的编译版本,sdk版本等,我们可以通过gradle设置,这样子设置的好处就是只要我们有修改需求,那么只是修改一个地方就好了,例子如下:
我们在项目目录下的gradle.properties文件中,添加如下代码
SDK_COMPILE_VSERION=23
SDK_TOOLS_VERSION= 23.0.2
SDK_MIN_SDK_VERSION=14
SDK_TARGET_SDK_VERSION=23
使用,在需要的module中的build.gradle设置如下:
compileSdkVersion Integer.valueOf(project.SDK_COMPILE_VSERION)
buildToolsVersion project.SDK_TOOLS_VERSION
defaultConfig {
applicationId "com.example.user.testproject"
minSdkVersion Integer.valueOf(project.SDK_MIN_SDK_VERSION)
targetSdkVersion Integer.valueOf(project.SDK_TARGET_SDK_VERSION)
versionCode 1
versionName "1.0"
}
这样子就可以使用了,你还可以添加其他的属性去设置每个module共同的东西。只要通过project去引用对应的属性就行了,假如我们的项目需要更换编译版本或者其他,我们只是需要在gradle.properties中修改就可以了。
定义编程生成的变量
比如有时候我们需要区分debug版本还是release版本,我们没有去判断签名来觉得是否是正式版本的时候,我们可以通过在对应模块的build.gradle中去添加一些我们需要编译生成之后才去确定的东西,例子如下:
buildTypes {
release {
buildConfigField ("Boolean","enableLog" ,"false")
buildConfigField ("String","HOST_URL" ,"\"releaseURL\"")
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
buildConfigField ("Boolean" ,"enableLog" ,"true")
buildConfigField ("String","HOST_URL" ,"\"debugURL\"")
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
他将会在BuildConfig这个编译之后生成的类中产生一个布尔类型的enableLog变量,一个String类型的HOST_URL变量,我们运行不同的builtType就可以有不同的值。他的使用时:
buildConfigField "Type","varName","Value"
Type可以是JAVA的基本类型其中一种,第二个是变量名,最后一个是变量值。这里需要注意的是String类型需要转义一下,我使用的AS版本是2.2,Gradle插件版本是2.2.1,Gradle版本是2.14.1,不知道其他版本是否也需要。自行测试。
在BuildConfig文件中,自动会为我们生成的变量有:
DEBUG 是否是debug,除了debug类型的BuildType,其他是false
APPLICATION_ID 包名
BUILD_TYPE 构建类型名,比如debug/release,或者是自定义的buildType
FLAVOR 变种名字,假如你有使用productFlavors,那么他将会有对应的值,否则会为null
VERSION_CODE 版本号
VERSION_NAME 版本名字
输出定制化apk名字
applicationVariants.all { variant ->
variant.outputs.each { output ->
if (output.outputFile != null && output.outputFile.name.endsWith(".apk")
&& variant.buildType.name.equals("release")) {
def file = output.outputFile;
def buildTime = new Date().format("yyyy-MM-dd")
def buildName = variant.flavorName;
output.outputFile = new File(file.parent, "${buildTime}-${buildName}-${variant.getVersionCode()}-release.apk")
}
}
}
这里就可以输出定制化的release包的名字,我们使用多渠道打包的时候就可以这样子去指定我们需要的apk名字。他只要是位于Android节点下面就可以了。当我们需要把打包出来的apk输出到指定目录的时候,只是需要把file.parent改为自己需要输出的目录就可以了。
编译优化
dexOptions {
javaMaxHeapSize "2g"
}
// 在一般在buildType为release的节点添加
//混淆
minifyEnabled true
//Zipalign优化
zipAlignEnabled true
//资源优化,去除无用资源
shrinkResources true
分包
由于Android apk方法引用数是short标记,所以我们的方法数目不能超出65535,一旦超出,我们就需要进行分包,分包的步骤,
1,引入依赖:
compile 'com.android.support:multidex:1.0.1'
2,在我们自定义的Application中加载:
public class DevApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
}
3,在gradle中开启分包和指定分包规则:
//在defaultConfig节点添加
multiDexEnabled true
//在android节点下面添加
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = []
}
dx.additionalParameters += '--multi-dex' // enable multidex
}
}
依赖冲突解决
使用packagingOptions,我们可以去除依赖中认为是不需要的内容,常用的有:
packagingOptions { // 打包配置
exclude 'META-INF/LICENSE' // 排除一些文件
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
当我们在依赖冲突的时候,只是使用其中的一个依赖库的一部分时候,使用例子如下
// 去除整个库,只是需要完整的groupId
exclude group: 'com.android.support'
//去除其中的一部分,需要groupId和artifactId
exclude group: 'com.android.support', module: 'support-annotations'
设置java版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
有时候比如我们需要使用lambda表达式的时候就可以使用。
1. 我们使用BuiltType+productFlavors的时候,他们的名字不能够相同。