Android Studio Gradle 進階設定
前言
一直想總結一些常用的 gradle 的用法,省的每次都要查閱,也方便自己複習和備忘。ps:最近也看到了一篇關於高效閱讀方法的文章,產生些許共鳴,也推薦給感興趣的人閱讀一下,沒準你也會喜歡!^_^
設定 Java 版本
如果想在某個 module 設定,可以在其 build.gradle 中配置:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
- 1
- 2
- 3
- 4
- 5
- 6
如果想要做全域性配置,那麼就在根目錄的 build.gradle 中配置:
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
全域性設定編碼
allprojects {
repositories {
jcenter()
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
定義全域性變數
先在 project 根目錄下的 build.gradle 定義全域性變數:
ext {
minSdkVersion = 16
targetSdkVersion = 24
}
- 1
- 2
- 3
- 4
然後在各 module 的 build.gradle 中可以通過rootProject.ext
來引用:
android {
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext .targetSdkVersion
}
- 1
- 2
- 3
- 4
- 5
定義區域性變數
有時候一個庫會被引用多次,或者一個庫有多個依賴,但這些依賴的版本都是統一的。我們通過ext來定義一些變數,這樣在用到的時候就可以統一使用了。
ext {
leakcanaryVersion = '1.3.1'
scalpelVersion = "1.1.2" // other param
}
- 1
- 2
- 3
- 4
debugCompile "com.squareup.leakcanary:leakcanary-android:$leakcanaryVersion"
releaseCompile "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanaryVersion"
- 1
- 2
exlude關鍵字
我們經常會遇到庫衝突的問題,這個在多個部門協作的大公司會更常見到。將衝突的庫通過exclude
來做剔除是一個好方法。
剔除整個組織的庫
compile ('com.facebook.fresco:animated-webp:0.13.0') {
exclude group: 'com.android.support' // 僅僅寫組織名稱
}
- 1
- 2
- 3
剔除某個庫
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'
}
- 1
- 2
- 3
- 4
- 5
- 6
引用本地aar
- 把aar檔案放在某目錄內,比如就放在某個 module 的 libs 目錄內
在這個 module 的 build.gradle 檔案中新增:
repositories {
flatDir {
dirs 'libs' //this way we can find the .aar file in libs folder
}
}
- 1
- 2
- 3
- 4
- 5
之後在其他專案中新增下面的程式碼後就引用了該 aar
dependencies {
compile(name:'aar的名字(不用加字尾)', ext:'aar')
}
- 1
- 2
- 3
如果你希望把 aar 放在專案的根目錄中,也可以參考上面的配置方案。在根目錄的build.gradle
中寫上:
allprojects {
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
依賴專案中的 module 和 jar
工程可以依賴自身的module和jar檔案,依賴方式如下:
dependencies {
compile project(':mylibraryModule')
compile files('libs/sdk-1.1.jar')
}
- 1
- 2
- 3
- 4
配置獨立的簽名信息
通常我們可以直接把簽名的明文資訊寫在 gradle 配置檔案中,但是在開原始碼的時候不是很方便,前者可能存放簽名檔案的位置需要修改,後者則希望隱藏簽名信息,在看不少開源專案的時候,發現很多是這樣做的 signingConfigs 位置, android 的下一級
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在對應位置引用常量,在 properties 中再進行具體賦值,這樣不會直接暴露簽名信息,也方便配置 在 gradle.properties 中
RELEASE_KEY_PASSWORD=xxxx
RELEASE_KEY_ALIAS=xxx
RELEASE_STORE_PASSWORD=xxx
RELEASE_STORE_FILE=../.keystore/xxx.jks
- 1
- 2
- 3
- 4
多渠道打包
在 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"]
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
替換 AndroiManifest 中的欄位
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}"/>
- 1
- 2
- 3
減少編譯錯誤和忽略 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
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
生成自定義 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")
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
指定資源目錄
自定義 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']
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
在 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'
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
在 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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果有帶引號的 string,要記得轉義:
buildConfigField "String", "URL_ENDPOINT", "\"http://your.development.endpoint.com/\""
- 1
結語
此外,gralde 設定可以結合 AndroidStudio 提供的圖形介面設定,理解會更快更透徹 File-Project Structure-Modules-app