在使用Android Studio過程中沒少被Gradle坑過,雖然網上有很多簡單粗暴的解決方案,但極少會說清楚緣由,所以一直想看一本叫《Android Gradle權威指南》。
不過由於書中實踐內容很多,更像一本工具書,而且Gradle現已發行了好幾版,因此本篇僅僅是陳列出一些大的要點,尤其是那些熟悉又陌生的名詞,如果想要具體瞭解細節和操作流程,一定要跟着書探索喲~
- Gradle入門
- Groovy基礎
- Gradle構建腳本基礎
- Gradle插件
- Java Gradle插件
- Android Gradle插件
一.Gradle入門
1.本書環境
- JDK:OpenJDK 1.8.0
- Gradle:Gradle 2.14.1 All 版
- IDE:Android Studio 2.2.3
- Android Plugin:Android Gradle 2.2.3
- Android:API 23
2.Eclipse和Android Studio
a.開發配置區別:
- Eclipse+ADT+Ant
- Android Studio+Gradle:Gradle比Ant更靈活,有效提高開發效率
b.Eclipse遷移到AndroidStudio兩種方式:
- 使用AndroidStudio直接導入Eclipse工程
- 特點:使用AS默認推薦目錄結構
- 使用Eclipse導出Android Gradle配置文件,並轉換成Gradle工程,再使用Android Studio把它作爲Gradle工程導入
- 特點:保留原項目結構
3.Gradle的ZIP解壓後目錄
- docs:API、 DSL、指南等文檔
- init.d:gradle初始化腳本目錄
- lib:相關庫
- media:一些icon資源
- samples:示例
- src:源文件
- getting-started.html:入門鏈接
- LICENSE
- NOTICE
4.引例:Gradle版Hello World
//build.gradle:
task hello{//定義一個任務Task名爲hello
doLast{//添加一個動作Action,表示在Task執行完畢後回調doLast閉包中的代碼
println'Hello World'//輸出字符串,單雙號均可
}
}
//終端:
gradle hello//執行build.gradle中名爲Hello的任務
//輸出:
Hello World
5.Gradle Wrapper
a.含義:對Gradle一層包裝,便於使用統一Gradle構建
b.目錄結構:
|--gradle
| |--wrapper
| |--gradle-wrapper.jar
| |--gradle-wrapper.properties
|--gradlew
|--gradlew.bat
gradle-wrapper.jar
:具體業務邏輯實現的jar包gradle-wrapper.properties
:配置文件,包含篇配置信息如下圖:
gradlew
:Linux下可執行腳本gradlew.bat
:Windows下可執行腳本
c.常用命令:
- 生成:
gradle wrapper
,由Wrapper Task生成 - 配置參數:
gradle wrapper --gradle-version XXX
用於指定使用的Gradle版本gradle wrapper --distribution-url XXX
用於指定下載Gradle發行版的url地址
- 自定義:
task wrapper(type:Wrapper){ //配置信息 }
6.Gradle日誌
a.日誌級別:
b.日誌輸出代碼:
- 使用print方法,屬於quiet級別日誌:
println 'XX'X
- 使用內置logger:
c.日誌輸出控制:
例如,輸出QUIET級別及其之上的日誌信息:gradle -q tasks
7.Gradle命令行
- 查看所有可執行tasks:
./gradlew tasks
- 強制刷新依賴:
./gradlew --refresh-dependencies assemble
- 多任務調用:
./gradlew clean jar
- 查看幫助:
./gradlew -?
或./gradlew -h
或./gradlew -help
二.Groovy基礎
一句話表明Groovy的地位:Groovy於Gradle,好比Java於Android
1.特性:Groovy是個靈活的動態腳本語言,語法和Java很相似,又兼容Java,且在此基礎上增加了很多動態類型和靈活的特性,如支持閉包和DSL
2.語法
- 分號不必需
- 字符串:單引號和雙引號均可定義一個字符串常量,區別在於單引號不能對字符串表達式做運算,而雙引號可以
task printStringVar << {
def name = "張三”
println '單引號的變量計算:${name}'
println "雙引號的變量計算:${name}"
}
運行./gradlew printStringVar輸出結果:
單引號的變量計算:${name}
雙引號的變量計算:張三
- 集合:以List和Map爲例,介紹如何定義集合和訪問集合元素
//List
task printList<<{
def numList = [1,2,3,4,5,6];//定義一個List
println numList[1]//輸出第二個元素
println numList[-1]//輸出最後一個元素
println numList[1..3]//輸出第二個到第四個元素
numList.each{
println it//輸出每個元素
}
}
//Map
task printlnMap<<{
def map1 =['width':1024,'height':768]//定義一個Map
println mapl['width']//輸出width的值
println mapl.height//輸出height的值
map1.each{
println "Key:${it.key},Value:${it.value}"//輸出所有鍵值對
}
}
- 方法:方法調用傳參的括號可省略;return不必需,無return時會將最後一行代碼作爲其返回值;允許將代碼塊(閉包)作爲參數傳遞
//以集合的each方法爲例,接受的參數就是一個閉包
numList.each({println it})
//省略傳參的括號,並調整格式,有以下常見形式
numList.each{
println it
}
- 不是一定要定義成員變量才能作爲類屬性被訪問,用get/set方法也能當作類屬性
task helloJavaBean<<{
Person p = new Person()
p.name = "張三"
println "名字是: ${p.name}"//輸出類屬性name,爲張三
println "年齡是: ${p.age}"//輸出類屬性age,爲12
}
class Person{
private String name
public int getAge(){//省略return
12
}
}
- 閉包:當閉包有一個參數時,默認爲it,多個參數時需要一一羅列
//單個參數
task helloClosure<<{
customEach{
println it
}
}
def customEach(closure){
for(int i in 1..10){
closure(i)
}
}
//多個參數
task helloClosure<<{
eachMap{k,v->
println "${k} is ${v}"
}
}
def eachMap(closure){
def map1 = ["name":"張三","age":18]
map1.each{
closure(it.key,it.value)
}
}
1.Settings文件
- 作用:初始化、設置工程樹
- 文件名:
settings.gradle
,放在Project下 - 常用方法:include方法指定能被Gradle識別的Module
//添加:app和:common這兩個module參與構建
include ':app'
project(':app').projectDir = new File('存放目錄')
include':common'
project(':common').projectDir = new File('存放目錄')
2.Build文件
- Project的
build.gradle
:整個Project的共有屬性,包括配置版本、插件、依賴庫等信息 - Module的
build.gradle
:各個module私有的配置文件
3.Gradle任務
a.含義:指原子性操作
b.關係:一個Gradle可包含多個Project,一個 Project可包含多個Task,即每個Project是由多個Task組成的;Task是Project的屬性,屬性名就是任務名
c.創建
- 以任務名創建:接受一個name參數
def task myTask = task(myTask)
myTask.doLast{
println "第一種創建Task方法,原型爲Task task(String name) throws InvalidUserDataException"
}
- 以任務名+Map創建:Map參數用於對創建的task進行配置,可用配置如下圖
def task myTask = task(myTask,group:BasePlugin.BUILD_GROUP)
myTask.doLast{
println "第二種創建Task方法,原型爲Task task(String name,Map<String,?> args) throws InvalidUserDataException"
}
- 以任務名+閉包創建:常見形式
task myTask{
doLast{
println "第三種創建Task方法,原型爲Task task(String name,Closure configureClosure)"
}
}
以上創建方式實際上最終都會調用
TaskContainter#create()
方法,使用./gradlew myTask
命令執行任務
d.訪問
- 通過任務名訪問:
名稱.方法
- 通過TaskContainter訪問:
tasks['名稱'].方法
- 通過路徑訪問:參數可以爲路徑或名稱
- get方式:
tasks.getByPath('路徑/名稱')
,若不存在會拋出UnknownTaskException異常 - find方式:
tasks.findByPath('路徑/名稱')
,若不存在返回null
- get方式:
- 通過名稱訪問:參數只能爲名稱
- get方式:
tasks.getByName('名稱')
,若不存在會拋出UnknownTaskException異常 - find方式:
tasks.findByName('名稱')
,若不存在返回null
- get方式:
可見任務名稱是唯一的,這是因爲TaskContainer的父類 NamedDomainObjectCopllection是個具有唯一不變名字的域對象的集合
e.依賴:在創建任務時通過dependsOn指定其依賴的任務,可以控制任務的執行順序
task task1<<{
println 'hello'
}
task task2<<{
println 'world'
}
//依賴單個任務
task task3(dependsOn:task1){
doLast{
println 'one'
}
}
//依賴多個任務
task task4{
dependsOn task1,task2
doLast{
println 'two'
}
}
當執行task4時,會發現task1、task2會先執行,再執行task4
注:操作符<< 用在Task定義上相當於doLast
f.排序:除了通過強依賴來控制任務的執行順序,還可以通過 shouldRunAfter
和 mustRunAfter
實現
taskB.shouldRunAfter(taskA) //表示taskB應該在taskA執行之後執行,有可能不會按預設執行
taskB.mustRunAfter(taskA) //表示taskB必須在taskA執行之後執行
g.分組& 描述:分組是對任務的分類,便於歸類整理;描述是說明任務的作用;建議兩個一起配置,便於快速瞭解任務的分類和用途
def task myTask = task(myTask)
myTask .group = BasePlugin.BUILD_GROUP
myTask .description = '這是一個構建的引導任務'
h.啓用 & 禁用:enable屬性可以啓動和禁用任務,執行被禁用的任務輸出提示該任務被跳過
def task myTask = task(myTask)
myTask.enable = false //禁用任務
i.執行分析:執行Task的時候實際上是執行其擁有的actions List,它是Task對象實例的成員變量;在創建任務時Gradle會解析其中被TaskAction註解的方法作爲其Task執行的action,並添加到 actions List,其中doFirst和doList會被添加到action List第一位和最後一位
4.自定義屬性
Project、Task和SourceSet都允許用戶添加額外的自定義屬性、並對自定義屬性進行讀取和設置
- 方式:通過ext屬性,添加多個通過ext代碼塊
- 優點:相比局部變量有廣泛的作用域,可以跨Project、跨Task訪問,只要能訪問這些屬性所屬的對象即可
//給Project添加自定義屬性
ext.age = 18
ext{
phone = 13888888888
address = 'Beijing'
}
//給Task添加自定義屬性
task customProperty {
ext.inner = 'innnnnner'
doLast{
println project.hasProperty('customProperty') //true
println project.hasProperty('age') //true
println project.hasProperty('inner')//返回fasle
println "${age}"
println "${phone}"
println "${inner}"
}
}
四.Gradle插件
1.作用
- 可以添加任務到項目,比如測試、編譯、打包等
- 可以添加依賴配置到項目,幫助配置項目構建過程中需要的依賴,比如第三方庫等
- 可以向項目中現有的對象類型添加新的擴展屬性和方法等,幫助配置和優化構建
- 可以對項目進行一些約定,比如約定源代碼存放位置等
Gradle本身內置許多常用的插件,如若需要還可以擴展現有插件或者自定義插件,如Android Gradle插件就是基於內置的Java插件實現的
2.擴展現有插件
a.插件種類
- 二進制插件:實現
org.gradle.api.Plugin
接口的插件,可以有plugin id - 腳本插件:嚴格上只是一個腳本,可以來自本地或網路
b.應用插件:通過Project#apply()
方法,有三種用法
- Map參數:
void apply (Map<String, ?> options)
- 二進制插件:
- id:
apply plugin:'java'
- 類型:
apply plugin:org.gradle.api.plugins.JavaPlugin
- 簡寫:
apply plugin:JavaPlugin
- id:
- 腳本插件:
apply from:'version.gradle'
- 第三方發佈插件:
apply plugin:'com.android.application'
- 二進制插件:
注意:應用第三方發佈的作爲jar的二進制插件時,必須先在
buildscript{}
配置其classpath才能使用,否則會提示找不到該插件
//buildscript:爲項目進行前提準備和初始化相關配置依賴
buildscript {
repositories {
jcenter ()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0"
}
}
apply plugin:'com.android.application
- 閉包:
void apply (Closure closure)
apply {
plugin:'java'
}
- Action:
void apply (Action<? super ObjectConfigurationActicn> action)
3.自定義插件:實現Plugin接口、重寫apply()方法
1.項目結構
使用Java插件要先應用進來:
apply plugin:'java'
此時會添加許多默認設置和約定,比如有以下默認項目結構:
|-example
| |-build.gradle
| |-src
| |-main
| |-java 源代碼存放目錄
| |-resources 打包文件存放目錄
| |-test
| |-java 單元測試用例存放目錄
| |-resources 單元測試中使用的文件
2.源集(SourceSet)
- 作用:用於描述和管理源代碼(java)及其資源(resources),如訪問源代碼目錄、設置源集屬性、更改Java原代碼目錄等
- 方式:通過
sourceSets
屬性(是一個SourceSetsContainer)和sourceSets{}
閉包 - 常用屬性:
比如,在上述Java插件默認項目結構中的main和test就是內置的兩個源集,現在更改main源集的Java源文件的存放目錄到src/java下:
apply plugin:'java'
sourceSets{
main{
java{
srcDir 'src/java'
}
}
}
- 定義新源集:通過
sourceSets{}
閉包添加
apply plugin:'java'
sourceSets{
vip{
}
}
此時會新建兩個目錄:src/vip/java和src/vip/resources
補充:除了SourceSet,Java插件裏常用的其他屬性:
3.配置第三方依賴
a.依賴方式
- 外部依賴:依賴外部倉庫,如Maven、Ivy等
- 項目依賴:依賴項目,依賴後可以使用該項目的Java類
- 文件依賴:如依賴Jar包,出於安全考慮不發佈到Maven而是放在項目的libs文件夾下
b.具體方法
- 對於外部依賴,需要先在
repositories{}
閉包裏聲明依賴庫的位置 - 在
dependencies{}
閉包添加依賴- 外部依賴:說明依賴庫的
group:name:version
- 項目依賴:
project('項目名稱')
- 文件依賴:
files('文件名稱')
,多個文件逗號分開,或者fileTree(dir:'文件名稱',include:'*.擴展名稱')
依賴指定文件夾下指定擴展名文件
- 外部依賴:說明依賴庫的
- 幾種依賴類型
舉例:
apply plugin:'java'
repositories {
//外部依賴 依賴Maven中心庫
maveCentral()
}
dependencies {
//外部依賴 完整寫法
compile group:'com.squareup.okhttp3',name:'okhttp', version:'3.0.1'
//外部依賴 簡單寫法
compile 'com.squareup.okhttp3:okhttp:3.0.1'
//外部依賴 指定main源集依賴
mainCompile 'com.squareup.okhttp3:okhttp:3.0.1'
//項目依賴
compile project(':example')
//文件依賴 依賴libs下兩個Jar包
compile files('libs/example01.jar', 'libs/example02.jar')
//文件依賴 指定依賴libs下所有Jar包
compile fileTree(dir: 'libs',include: '*.jar')
}
4.內置任務
常用幾種任務:
build
任務:構建項目clean
任務:刪除build目錄及構建生成的文件assemble
任務:不執行單元測試,只編譯和打包check
任務:只執行單元測試javadoc
任務:生成Java格式的doc api文檔
還有些通用任務、對源集適用的任務:
5.多項目構建
- 含義:多個Gradle項目一起構建
- 方式:通過
settings.gradle
配置管理多項目;在每個項目都有一個build.gradle
,採用項目依賴就能實現多項目協作
//settings.gradle
include ':app'
project(':app').projectDir = new File('存放目錄')
include ':base'
project(':base').projectDir = new File('存放目錄')
//app/build.gradle
apply plugin:'java'
dependencies {
compile project(':base')
}
6.發佈構件
- 構件:Gradle構建的產物,如Jar包、Zip包等
- 意義:發佈構建給其他工程使用,可以發佈到本地目錄、Maven、Ivy等
- 方式:明確構件類型,並通過
artifacts{}
閉包配置需要發佈的構建,在uploadArchives{}
上傳發布構件
//以發佈jar構件爲例
apply plugin:'java '
task publishJar(type:Jar)
artifacts{
archives publishJar
}
uploadArchives{
repositories{
//發佈到本地目錄
flatDir{
name 'libs'
dirs "$projectDir/libs"
}
//發佈到本地Maven庫
mavenLocal()
}
}
1.概述
Android Gradle插件繼承於Java插件,具有Java插件的所有特性,也有自己的特性,看下官方介紹:
- 可以很容易地重用代碼和資源
- 可以很容易地創建應用的衍生版本
- 可以很容易地配置、擴展以及自定義構建過程
- 和IDE無縫整合
2.插件分類
- App應用工程:生成可運行apk應用;id:
com.android.application
- Library庫工程:生成aar包給其他的App工程公用;id:
com.android.library
- Test測試工程:對App應用工程或Library庫工程進行單元測試;id:
com.android.test
3.項目結構
|-example
| |-build.gradle
| |-example.iml
| |-libs
| |-proguard-rules.pro 混淆配置文件
| |-src
| |-androidTest
| |-java Android單元測試代碼
| |-main
| |-java App主代碼
| |-res 資源文件
| |-AndroidManifest.xml 配置文件
| |-test
| |-java 普通單元測試代碼
4.內置任務
- Java插件內置任務:如build、assemble、check等
- Android特有的常用任務:
connectedCheck
任務:在所有連接的設備或者模擬器上運行check檢查deviceCheck
任務:通過API連接遠程設備運行checkslint
任務:在所有ProductFlavor上運行lint檢查install
、uninstall
任務:在已連接的設備上安裝或者卸載AppsigningReport
任務:打印App簽名androidDependencies
任務:打印Android 依賴
5.應用實例
//應用插件,Android Gradle屬於Android發佈的第三方插件
buildscript{
repositories{
jcenter()
}
dependencies{
classpath 'com.android.tcols.build:gradle:1.5.0'
}
}
apply plugin:'com.android.application'
//自定義配置入口,後續詳解
android{
compileSdkVersion 23 //編譯Android工程的SDK版本
buildToolsVersion "23.0.1" //構建Android工程所用的構建工具版本
defaultConfig{
applicationId "org.minmin.app.example"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes{
release{
minifyEnabled false
proguardFiles getDefaultPraguardFile('proguard-andrcid.txt'), 'proguard-rules.pro'
}
}
}
//配置第三方依賴
dependencies{
compile fileTree(dir:'libs', include:['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcorpat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
}
a.defaultConfig
- 作用:用於定義所有的默認配置,是一個ProductFlavor,若ProductFlavor沒有被特殊定義,默認使用defaultConfig塊指定的配置
- 常用配置:
屬性名 | 含義 |
---|---|
applicationId | 指定App包名 |
minSdkVersion | 指定App最低支持的Android SDK |
targetSdkVersion | 指定基於的Android SDK |
versionCode | 配置Android App的內部版本號 |
versionName | 配置Android App的版本名稱 |
testApplicationId | 配置測試App的包名,默認爲applicationId + “.test” |
testInstrumentationRunner | 配置單元測試使用的Runner,默認爲android.test.InstrumentationTestRunner |
proguardFile | 配置App ProGuard混淆所使用的ProGuard配置文件 |
proguardFiles | 同時配置多個ProGuard配置文件 |
signingConfig | 配置默認的簽名信息,也是一個ProductFlavor,可直接配置 |
b.buildTypes
- 作用:是構建類型,在Android Gradle中內置了debug和release兩個構建類型,差別在於能否在設備上調試和簽名不同
- 每一個BuildType都會生成一個SourceSet以及相應的
assemble<BuildTypeName>
任務 - 常用配置:
屬性名 | 含義 |
---|---|
applicationIdSuffix | 配置基於默認applicationId的後綴 |
debuggable | 是否生成一個可供調試的Apk |
jniDebuggable | 是否生成一個可供調試JNI代碼的Apk |
minifyEnabled | 是否啓用Proguard混淆 |
multiDexEnabled | 是否啓用自動拆分多個Dex的功能 |
zipAlignEnabled | 是否開啓開啓zipalign優化,提高apk運行效率 |
shrinkResources | 是否自動清理未使用的資源,默認爲false |
proguardFile | 配置Proguard混淆使用的配置文件 |
proguardFiles | 同時配置多個ProGuard配置文件 |
signingConfig | 配置默認的簽名信息,也是一個ProductFlavor,可直接配置 |
c.signingConfigs
- 作用:配置簽名設置,標記App唯一性、保護App
- 可以對不同構建類型採用不同簽名方式:debug模式用於開發調試,可以直接使用Android SDK提供的默認debug簽名證書;release模式用於發佈,需要手動配置
- 常用配置:
屬性名 | 含義 |
---|---|
storeFile | 簽名證書文件 |
storePassword | 簽名證書文件的密碼 |
storeType | 簽名證書的類型 |
keyAlias | 簽名證書中密鑰別名 |
keyPassword | 簽名證書中該密鑰的密碼 |
android {
signingConfigs {
release{
storeFile file('myFile.keystore')
storePassword 'psw'
keyAlias 'myKey'
keyPassword 'psw'
}
}
}
d.productFlavors
- 作用:添加不同的渠道、並對其做不同的處理
- 常用配置:
屬性名 | 含義 |
---|---|
applicationId | 設置該渠道的包名 |
consumerProguardFiles | 對aar包進行混淆 |
manifestPlaceholders | |
multiDexEnabled | 啓用多個dex的配置,可突破65535方法問題 |
proguardFiles | 混淆使用的文件配置 |
signingConfig | 簽名配置 |
testApplicationId | 適配測試包的包名 |
testFunctionalTest | 是否是功能測試 |
testHandleProfiling | 是否啓用分析功能 |
testInstrumentationRunner | 配置運行測試使用的Instrumentation Runner的類名 |
testInstrumentationRunnerArguments | 配置Instrumentation Runner使用的參數 |
useJack | 標記是否啓用Jack和Jill這個全新的、高性能的編譯器 |
dimension | 維度,通過flavorDimensions方法聲明,聲明前後代表優先級 |
//定義baidu和google兩個渠道,並聲明兩個維度,優先級爲abi>version>defaultConfig
android{
flavorDimensions "abi", "version"
productFlavors{
google{
dimension "abi"
}
baidu{
dimension "version"
}
}
e.buildConfigFiled
- 作用:在buildTypes、ProductFlavor自定義字段等配置
- 方法:
buildConfigField(String type,String name,String value)
- type:字段類型
- name:字段常量名
- value:字段常量值
android{
buildTypes{
debug{
buildConfigField "boolean", "LOG_DEBUG", "true"
buildConfigField "String", "URL", ' "http://www.ecjtu.jx.cn/" '
}
}
}
6.多項目構建
和Java Grdle多項目構建一樣的,通過settings.gradle
配置管理多項目;在每個項目都有一個build.gradle
,採用項目依賴就能實現多項目協作。
項目直接依賴一般適用於關聯較緊密、不可複用的項目,如果想讓項目被其他項目所複用,比如公共組件庫、工具庫等,可以單獨發佈出去。
7.多渠道構建
a.基本原理
- 構建變體(Build Variant)=構建類型(Build Type)+構建渠道(Product Flavor)
Build Type有release、debug兩種構建類型
Product Flavor有baidu、google兩種構建渠道
Build Variant有baiduRelease、baiduDebug、googleRelease、googleDebug四種構件產出
-
構建渠道(Product Flavor)還可以通過dimension進一步細化分組
-
assemble開頭的負責生成構件產物(Apk)
assembleBaidu:運行後會生成baidu渠道的release和debug包
assembleRelease:運行後會生成所有渠道的release包
assembleBaiduRelease:運行後只會生成baidu的release包
b.構建方式:通過佔位符manifestPlaceholders
實現:
//AndroidManifest
<meta-data
android: value="Channel ID"
android:name="UMENG_ CHANNEL"/>
//build.gradle
android{
productFlavors{
google{
manifestPlaceholders.put("UMENG_ CHANNEL", "google")
}
baidu{
manifestPlaceholders.put("UMENG_ CHANEL", "baidu")
}
}
//改進:通過productFlavors批量修改
android{
productFlavors{
google{
}
baidu{
}
ProductFlavors.all{ flavor->
manifestPlaceholders.put("UMENG_ CHANEL", name)
}
}
8.高級應用
a. 使用共享庫
- android sdk庫:系統會自動鏈接
- 共享庫:獨立庫,不會被系統自動鏈接,使用時需要在AndroidManifest通過
<uses-library>
指定
//聲明需要使用maps共享庫,true表示如果手機系統不滿足將不能安裝該應用
<uses-library
android:name="com.google.android.maps"
android:required="true"
/>
- add-ons庫:存於add-ons目錄下,大部分由第三方廠商或公司開發,會被自動解析添加到classpath
- optional可選庫:位於platforms/android-xx/optional目錄下,通常爲了兼容舊版本的API,使用時需要手動添加到classpath
b. 批量修改生成的apk文件名
- 類型:
applicationVariants
:僅僅適用於Android應用Gradle插件libraryVariants
:僅僅適用於Android庫Gradle插件testVariants
:以上兩種Gradle插件都使用
- 示例:
applicationVariants
是一個DomainObjectCollection集合,通過all方法遍歷每一個ApplicationVariant,這裏有googleRelease和googleDebug兩個變體;然後判斷名字是否以.apk結尾,如果是就修改其文件名。示例中共有。
c.動態生成版本信息
- 原始方式:由
defaultConfig
中的versionName
指定 - 分模塊方式:把版本號等配置抽出放在單獨的文件裏,並用
ext{}
括起來,通過apply from將其引入到build.gradle,版本信息就被當作擴展屬性直接使用了 - 從git的tag中獲取
- 從屬性文件中動態獲取和遞增
d.隱藏簽名文件信息
- 必要性:爲保證簽名信息安全,最好直接放在項目中,而是放在服務器上
- 一種思路:
- 服務器:配置好環境變量,打包時直接使用
- 本地:直接使用android提供的debug簽名
- 在signingConfigs加入以下判斷
signingConfigs {
if (System.env.KEYSTORE_PATH != null) {
//打包服務器走這個邏輯
storeFile file(System.env.KEYSTORE_PATH)
keyAlias System.env.ALIAS
keyPassword System.env.KEYPASS
storePassword System.env.STOREPASS
} else {
//當不能從環境變量取到簽名信息時,使用本地debug簽名
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
e.動態添加自定義的資源
- 針對res/values中的資源,除了使用xml定義,還可以通過Android Gradle定義
- 方法:resValue(String type, String name, String value)
- type:資源類型,如有string、id、bool
- name:資源名稱,以便在工程中引用
- value:資源值
productFlavors{
google{
resValue 'string', 'channel_tips', 'google渠道歡迎你'
}
}
以google爲例,在debug模式下,資源文件保存目錄:build/generated/res/resValues/google/debug/values/generated.xml
f.Java編譯選項
通過compileOptions{}
閉包進行編譯配置,可配置項:
- encoding:配置源文件的編碼
- sourceCompatibility:配置Java源代碼的編譯級別
- targetCompatibility:配置生成Java字節碼的版本
android{
compileOptions{
encoding = 'utf-8'
sourceCompatibility = JavaVersion.VERSI0N_ 1_ 6
targetCompatibility = JavaVersion.VERSION_ 1_ 6
}
}
g. adb選項配置
通過adbOptions{}
閉包進行adb配置,可配置項:
- timeOutInMs:設置執行adb命令的超時時間,單位毫秒
- installOptions:設置adb install安裝設置項
- -l:鎖定該應用程序
- -r:替換已存在的應用程序,即強制安裝
- -t:允許測試包
- -s:把應用程序安裝到SD卡上
- -d:允許進行降級安裝,即安裝版本比手機自帶的低
- -g:爲該應用授予所有運行時的權限
android{
adbOptions{
timeOutInMs = 5*1000
installOptions '-r', '-s'
}
}
h.DEX選項配置
通過dexOptions {}
閉包進行dex配置,可配置項:
- incremental:配置是否啓用dx的增量模式,默認值爲false
- javaMaxHeapSize:配置執行dx命令時爲其分配的最大堆內存
- jumboMode:配置是否開啓jumbo模式
- preDexLibraries:配置是否預dex Libraries庫工程,默認值爲true,開啓後會提高增量構建的速度
- threadCount:配置Android Gradle運行dx命令時使用的線程數量