前言
一直想总结一些常用的 gradle 的用法,省的每次都要查阅,也方便自己复习和备忘。ps:最近也看到了一篇关于高效阅读方法的文章,产生些许共鸣,也推荐给感兴趣的人阅读一下,没准你也会喜欢!^_^
传送门:怎样读一本书
设置 Java 版本
如果想在某个 module 设置,可以在其 build.gradle 中配置:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
如果想要做全局配置,那么就在根目录的 build.gradle 中配置:
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
全局设定编码
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
}
定义全局变量
先在 project 根目录下的 build.gradle 定义全局变量:
ext {
minSdkVersion = 16
targetSdkVersion = 24
}
然后在各 module 的 build.gradle 中可以通过rootProject.ext
来引用:
android {
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
}
定义局部变量
有时候一个库会被引用多次,或者一个库有多个依赖,但这些依赖的版本都是统一的。我们通过ext来定义一些变量,这样在用到的时候就可以统一使用了。
ext {
leakcanaryVersion = '1.3.1'
scalpelVersion = "1.1.2" // other param
}
debugCompile "com.squareup.leakcanary:leakcanary-android:$leakcanaryVersion"
releaseCompile "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanaryVersion"
exlude关键字
我们经常会遇到库冲突的问题,这个在多个部门协作的大公司会更常见到。将冲突的库通过exclude
来做剔除是一个好方法。
- 剔除整个组织的库
compile ('com.facebook.fresco:animated-webp:0.13.0') {
exclude group: 'com.android.support' // 仅仅写组织名称
}
- 剔除某个库
compile('com.android.support:appcompat-v7:23.2.0') {
exclude group: 'com.android.support', module: 'support-annotations' // 写全称
exclude group: 'com.android.support', module: 'support-compat'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'support-vector-drawable'
}
引用本地aar
- 把aar文件放在某目录内,比如就放在某个 module 的 libs 目录内
- 在这个 module 的 build.gradle 文件中添加:
repositories {
flatDir {
dirs 'libs' //this way we can find the .aar file in libs folder
}
}
- 之后在其他项目中添加下面的代码后就引用了该 aar
dependencies {
compile(name:'aar的名字(不用加后缀)', ext:'aar')
}
如果你希望把 aar 放在项目的根目录中,也可以参考上面的配置方案。在根目录的build.gradle
中写上:
allprojects {
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
}
依赖项目中的 module 和 jar
工程可以依赖自身的module和jar文件,依赖方式如下:
dependencies {
compile project(':mylibraryModule')
compile files('libs/sdk-1.1.jar')
}
配置独立的签名信息
通常我们可以直接把签名的明文信息写在 gradle 配置文件中,但是在开源代码的时候不是很方便,前者可能存放签名文件的位置需要修改,后者则希望隐藏签名信息,在看不少开源项目的时候,发现很多是这样做的 signingConfigs 位置, android 的下一级
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
在对应位置引用常量,在 properties 中再进行具体赋值,这样不会直接暴露签名信息,也方便配置
在 gradle.properties 中
RELEASE_KEY_PASSWORD=xxxx
RELEASE_KEY_ALIAS=xxx
RELEASE_STORE_PASSWORD=xxx
RELEASE_STORE_FILE=../.keystore/xxx.jks
多渠道打包
在 product flavor 下定义不同类型, 把 AndroiManifest 中的 channel 替换
productFlavors 位置: android 的下一级
android {
productFlavors {
fir {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "fir"]
}
GooglePlay {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "GooglePlay"]
}
Umeng {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "Umeng"]
}
}
}
替换 AndroiManifest 中的字段
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}"/>
减少编译错误和忽略 lint 检查
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
}
lintOptions {
abortOnError false
}
生成自定义 App 名称
//生成自定义App名称
def generateAppName(variant) {
variant.outputs.each { output ->
def file = output.outputFile
output.outputFile = new File(file.parent, "Gank.IO-V" + android.defaultConfig.versionName + ".apk")
}
}
指定资源目录
自定义 java 代码和 res 资源的目录,更加灵活
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
if (!IS_USE_DATABINDING) { // 如果用了databinding
jniLibs.srcDirs = ['libs']
res.srcDirs = ['res', 'res-vm'] // 多加了databinding的资源目录
} else {
res.srcDirs = ['res']
}
}
test {
java.srcDirs = ['test']
}
androidTest {
java.srcDirs = ['androidTest']
}
}
}
在 BuildConfig.class 中增加静态变量
有时候我们想根据不同的版本,设置相同变量不同的值,最常见的使用场景就是 Log 工具类,通过设置 isDubug 不同值,只有 debug 版本的 app 会产生 log 日志,设置过程如下:
buildTypes {
release {
buildConfigField("boolean", "isDebug", "false") // 定义 isdubug 的值
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
buildConfigField("boolean", "isDebug", "true")
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
在 sync 后BuildConfig
中就有你定义的这个变量(isDebug)。
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.hiwhitley.himei";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
// Fields from build type: debug
public static final boolean isDebug = true;
}
如果有带引号的 string,要记得转义:
buildConfigField "String", "URL_ENDPOINT", "\"http://your.development.endpoint.com/\""
结语
此外,gralde 设置可以结合 AndroidStudio 提供的图形界面设置,理解会更快更透彻
File-Project Structure-Modules-app
参考