Android插件
前面我們說到Gradle插件其實并沒有提供真正的構(gòu)建功能, 我們編譯構(gòu)建的Task很多都是由插件來提供的扎附,如果對這點還不是很了解可以先看下Gradle腳本學(xué)習(xí)
Java插件
在某種意義上,android插件算是在java插件的基礎(chǔ)上擴(kuò)展而來的筹误,而java插件也是Gradle官方支持的插件之一,為了讓大家能夠更好的理解Android插件中各個Task的執(zhí)行和依賴關(guān)系躯泰,我們現(xiàn)對Java插件做一個介紹,英語好的同學(xué)可以直接去閱讀Gradle官方The Java Plugin
Java插件的使用很簡單华糖,畢竟是官方支持的
apply plugin: 'java'
這樣就可以了麦向,對于java插件我們主要理解一張Tasks圖表
這里包含了java插件中的絕大部分Tasks,圖標(biāo)中的Task描述如下
名稱 | 依賴 | TaskType | 描述 |
---|---|---|---|
compileJava | 所有處理編譯過程的任務(wù) | JavaCompile | 使用javac編譯java源碼 |
processResources | - | Copy | 把資源文件復(fù)制到相應(yīng)目錄 |
classes | complileJava和processResources | Task | 生成.class文件和資源文件目錄 |
compileTestJava | compile客叉,加上編譯測試文件的所有Task | JavaCompile | 使用javac編譯java測試代碼 |
processTestResources | - | Copy | 把測試資源文件復(fù)制到相應(yīng)目錄 |
testClasses | compileTestJava和processTestResources | Task | 申城測試的.class文件和資源文件目錄 |
jar | compile | Jar | 生產(chǎn)jar文件 |
javadoc | compile | Javadoc | 使用javadoc生產(chǎn)Api文檔 |
test | compile | Test | 使用JUnit或TestNG運行單元測試 |
uploadArchives | 生成所有archives需要的artifacts文件的Task诵竭,包括jar | Upload | 使用archives配置上傳artifacts包括jar文件 |
assemble | 項目中的所有archive任務(wù),包括jar | Task | 生成項目所有的archive文件 |
check | 項目中的所有驗證任務(wù)十办,包括test | Task | 執(zhí)行所有項目中的驗證任務(wù) |
build | assemble和check | Task | 執(zhí)行完整的項目構(gòu)建 |
clean | - | Delete | 刪除項目構(gòu)建過程生成的文件目錄 |
clean TaskName | - | Delete | 刪除指定任務(wù)創(chuàng)建的文件秀撇。 cleanJar將刪除由jar任務(wù)創(chuàng)建的JAR文件,cleanTest將刪除測試任務(wù)創(chuàng)建的文件 |
我們平時使用當(dāng)然不可能一步步去編譯向族,往往只會使用幾個相對簡單的命令呵燕,比如check、assemable之類的件相,但是如果我們對整個build的流程不了解再扭,我們就很難在構(gòu)建過程中對某一個具體的行為進(jìn)行優(yōu)化,這里先講解java插件夜矗,是因為java的構(gòu)建過程相對簡明泛范,Android工程的構(gòu)建過程就相對復(fù)雜很多,但是本質(zhì)上都差不多紊撕,建議大家還是可以先學(xué)習(xí)下
Android插件
Android插件是由google提供罢荡,用于配置、編譯对扶、打包android工程区赵,它提供了一些新的DSL和task供我們配置,執(zhí)行android工程的編譯打包過程浪南,關(guān)于android插件的使用個人建議可以看下Google提供的GradlePluginUserGuide和AndroidPluginDSL,這里我就算是拋磚引玉了
基本配置
android下最基本的配置很簡單笼才,完成最基本的配置之后Gradle就能夠?qū)ξ覀兊膒roject進(jìn)行構(gòu)建,同時還有一些的零碎的配置络凿,我也一并并在這里進(jìn)行說明最最簡單的骡送,我們只需要配置compileSdkVersion和buildtoolsVersion
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
}
這樣就可以完成構(gòu)建,當(dāng)然我們還需要配置一些Apk的基本信息絮记,這些信息主要通過defaultConfig{}來進(jìn)行配置摔踱,主要的信息如下
minSdkVersion
targetSdkVersion
versionCode
versionName
applicationId
-
testApplicationId
(used by the test APK) testInstrumentationRunner
前四條都是一些基本的版本配置信息其中值得一提的是applicationId
這條屬性,形式上和packageName是一致的到千,當(dāng)我們使用AndroidStudio創(chuàng)建工程是昌渤,applicationId默認(rèn)是和packageName一樣,但是這兩者是有本質(zhì)區(qū)別的憔四,packageName是可以改變的膀息,但是applicationId一旦應(yīng)用發(fā)布就不能修改了般眉,applicationId是APK的標(biāo)識,同時不同渠道版本的applicationId最好也進(jìn)行不同的配置潜支,這個稍后進(jìn)行詳細(xì)說明
關(guān)于test的配置信息甸赃,也會在后面的章節(jié)詳細(xì)說明
sourceSets
資源目錄Android插件的默認(rèn)資源目錄如下
src/
├──main/
│ ├── java/
│ ├── resources/
│ ├── res/
│ ├── assets/
│ ├── aidl/
│ ├── rs/
│ ├── jni/
│ ├── jniLibs/
│ └── AndroidManifest.xml
├── test/
└── androidTest/
如果需要更改目錄需要手動修改,例如對于一般的eclipse工程我們可以使用下面的配置
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest.setRoot('tests')
}
}
這樣就無需手動更改文件目錄冗酿,也可以直接編譯
Dependencies Configration
前面我們說到dependencies本質(zhì)上就是一個配置信息埠对,Android插件提供的dependencies主要有:
- compile: main application
- androidTestCompile: test application
- debugCompile: debug Build Type
- releaseCompile: release Build Type
- testComplie:上面四種是google官方文檔上寫的,事實上testComplie這種純java的test配置也是支持的
根據(jù)版本變種裁替,android插件也會生成不同的dependencies项玛,就像android自帶的兩種buildtype就生成了上面兩種dependencies
Android Tasks
前面在gradle我們說到,在gradle中實際的執(zhí)行是通過Task來進(jìn)行的弱判,Android插件能夠?qū)ξ覀兊腜roject進(jìn)行構(gòu)建襟沮,必然也提供了相應(yīng)的Task才能完成構(gòu)建,我們主要要用到的主要有下面幾個
- assemble生成輸出昌腰,會執(zhí)行構(gòu)建過程
- check運行所有檢查任務(wù)
- connectedCheck運行檢查連接的設(shè)備或模擬器开伏,所有連接的設(shè)備將并行運行。
- deviceCheck使用API??運行檢查以連接到遠(yuǎn)程設(shè)備遭商,這在CI服務(wù)器上使用固灵。
- build這個任務(wù)會運行assemble和check。
- clean此任務(wù)清除項目的輸出劫流。
感覺和java插件大體相似巫玻,只是多了兩個類似設(shè)備檢查之類的task,但是事實上祠汇,android工程的構(gòu)建過程還是比較復(fù)雜的大审,所以android插件并沒有給出構(gòu)建過程中具體的tasks,以及task間的依賴關(guān)系座哩,更沒有java插件中提供的task依賴表。
那么我們要怎么才能弄清android構(gòu)建的具體過程呢粮彤,這里我為大家介紹一個插件Inspector根穷,具體使用方法參考GitHub:https://github.com/jakeouellette/inspector,我就不多做介紹,這個插件可以生成我們所運行的task的依賴關(guān)系圖导坟,方便大家理解學(xué)習(xí)屿良。
注意:Inspector不支持windows!不支持windows惫周!不支持windows尘惧!
版本變種的配置
BuildType配置
版本變種中有兩個內(nèi)容,BuildType和ProductFlavor递递,首先是關(guān)于BuildType喷橙,Android插件默認(rèn)提供debug和release兩種BuildType啥么,當(dāng)然我們也可以自己添加新的BuildType,Android下對于每一種BuildType都可以有各自的配置信息贰逾,同時可以根據(jù)配置信息生成獨特apk悬荣,首先對于不同的BuildType,我們會有不同的dependencies配置compile類型疙剑,就像上面 dubugCompile一樣氯迂,類似下面的代碼
android {
buildTypes {
jnidebug {
}
}
}
就會生成一個jnidebugCompile,前面我們說過aseemble這個task可以生產(chǎn)所有的輸出言缤,這里我們有三個BuildType嚼蚀,即assemble會生成3個不同Apk,如果我們只需要生成debug的Apk管挟,這里和compile一樣轿曙,Android插件也會生成一個assembleDubug的task,運行assembleDubug則不會生成其他版本的Apk
BuildType的配置就在buildTypes{}的閉包中
android {
buildTypes {
debug {
applicationIdSuffix ".debug"
}
jnidebug {
initWith(buildTypes.debug)
applicationIdSuffix ".jnidebug"
jniDebuggable true
}
}
}
其實我覺得這些東西反而沒有什么好講的哮独,配置基本上就是一個表拳芙,列出所有可配置的東西,這里我姑且還是把一些我感覺可用的配置和方法都列出來皮璧,大家也可以參考官方文檔
名稱|類型|說明
---|--|--|--
applicationIdSuffix|String|為 applicationId添加后綴舟扎,applicationId是app唯一標(biāo)識,每次調(diào)用都是在最開始的applicationId上添加
debuggable|Boolean|調(diào)試開關(guān)
consumerProguardFiles|List<File>|生成的aar文件中的混淆規(guī)則悴务,只針對Library工程
jniDebuggable|Boolean|jniDebug開關(guān)
minifyEnabled|Boolean|混淆開關(guān)
signingConfig|SigningConfig|簽名配置
proguardFiles|List<File>|生成apk時使用的混淆配置文件
shrinkResources|Boolean|移除沒有用到的資源文件睹限,默認(rèn)為false
embedMicroApp|Boolean|Android Wear app是否需要嵌入此build type
manifestPlaceholders|Map<String, Object>|配置manifest屬性,合并時使用這里的屬性
multiDexEnabled|Boolean|Multi-Dex開關(guān)
multiDexKeepFile|File|main dex的配置文件讯檐,text文件羡疗,每行指定一個class文件,格式為com/example/MyClass.class
multiDexKeepProguard|File|main dex的混淆規(guī)則别洪,會和構(gòu)建系統(tǒng)的混淆規(guī)則合并
zipAlignEnabled|Boolean|壓縮對齊開關(guān)
[buildConfigField](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html#com.android.build.gradle.internal.dsl.BuildType:buildConfigField(java.lang.String, java.lang.String, java.lang.String))(String, String, String)|Method|為生成的BuildConfig添加鍵值對
initWith(BuildType)|Method|復(fù)制所有屬性
SigningConfig
Android 要求所有 APK 必須先使用證書進(jìn)行數(shù)字簽署叨恨,然后才能安裝。Android插件已經(jīng)幫我們配置了兩種BuildType:debug和release挖垛,其中debug默認(rèn)使用Android自動生成的dubug Signing痒钝,而release默認(rèn)是沒有配置Signing的,我們可以直接在代碼中進(jìn)行Signing的配置
android {
signingConfigs {
release{
storeFile file("other.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
buildTypes {
release{
signingConfig signingConfigs.release
}
}
}
這里我們我們通過signingConfigs{}配置了一個release的signing痢毒,然后在配置buildTypes 的時候把它配置到送矩,release的配置閉包中, 這里可以簡單的把signingConfigs理解為一個配置文件哪替,在上面我們直接keystore的pwd寫在了代碼中栋荸, 一般是不建議這么,我們通常使用一個專門的配置文件來存儲signingConfigs,需要的時候從文件中讀取晌块,或者從控制臺輸入爱沟。
BuildConfig
在編譯時期,Android插件會生成一個BuildConfig的類摸袁,包含部分Gralde配置中的常量默認(rèn)BuildConfig有下列信息:
- boolean DEBUG 是否可以dubug
- int VERSION_CODE
- String VERSION_NAME
- String APPLICATION_ID
- String BUILD_TYPE – name of the build type, e.g. "release"
- String FLAVOR – name of the flavor, e.g. "paidapp"
同時我們也可以通過buildConfigField(String, String, String)把我們需要的配置信息加入到BuildConfig中
ProductFlavor配置
ProductFlavor的配置和BuildType基本類似钥顽,同時也會生成相應(yīng)的Task和Compile,主要區(qū)別就是BuildType的分類是針對開發(fā)者的靠汁,如debug蜂大、release,而ProductFlavor的分類是針對用戶的蝶怔,如free奶浦、pay,所以可配置的內(nèi)容是不同的踢星,ProductFlavor的配置信息主要如下:
名稱|類型|說明
---|--|--|--
applicationId|String|-
applicationIdSuffix|String|為 applicationId添加后綴澳叉,applicationId是app唯一標(biāo)識,每次調(diào)用都是在最開始的applicationId上添加
consumerProguardFiles|List<File>|生成的aar文件中的混淆規(guī)則沐悦,只針對Library工程
dimension|String|此flavor的dimensioin類型
externalNativeBuild|ExternalNativeBuildOptions|封裝了native相關(guān)構(gòu)建的信息
jackOptions|JackOptions|jack配置
signingConfig|SigningConfig|簽名配置
proguardFiles|List<File>|生成apk時使用的混淆配置文件
manifestPlaceholders|Map<String, Object>|配置manifest屬性成洗,合并時使用這里的屬性
multiDexEnabled|Boolean|Multi-Dex開關(guān)
multiDexKeepFile|File|main dex的配置文件,text文件藏否,每行指定一個class文件瓶殃,格式為com/example/MyClass.class
multiDexKeepProguard|File|main dex的混淆規(guī)則,會和構(gòu)建系統(tǒng)的混淆規(guī)則合并
[buildConfigField](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html#com.android.build.gradle.internal.dsl.BuildType:buildConfigField(java.lang.String, java.lang.String, java.lang.String))(String, String, String)|Method|為生成的BuildConfig添加鍵值對
maxSdkVersion(int or String)|Method|設(shè)置flavor最高sdk版本
minSdkVersion(int or String)|Method|設(shè)置flavor最低sdk版本
Build Variant
我們知道一種BuildType會生產(chǎn)一種Apk副签,ProductFlavor也是一樣的遥椿,那個一個工程可以產(chǎn)出的不同種類的apk將是這兩者的合并,比如一個有兩個Flavor的工程,加上默認(rèn)的BuildType淆储,則會生成下面幾個版本:
- Flavor1 - debug
- Flavor1 - release
- Flavor2 - debug
- Flavor2 - release
Build Type + Product Flavor = Build Variant
Sourcesets and Dependencies
不同的BuildVariant可以有不同的資源和依賴冠场,他們同時共享主目錄下的資源,舉個例子flavor1Debug這樣一個Variant本砰,它的資源可能來自如下目錄
-
android.sourceSets.main
位于 src/main/ -
android.sourceSets.flavor1
位于 src/flavor1/ -
android.sourceSets.debug
位于 src/debug/ -
android.sourceSets.flavor1Debug
位于 src/flavor1Debug/
如果出現(xiàn)同名的文件那么他們的優(yōu)先級順序是flavor1Debug>debug>flavor1>main,一層會覆蓋一層碴裙。對于Dependencies,這個規(guī)則也是一樣的点额。
小結(jié)
Android插件的內(nèi)容并不算多青团,但是想要用好Gradle,我們除了要了解這些東西之外咖楣,還需要了解Gradle和Groovy提供的API以及一些其他的插件才能更好的使用它。