Android插件
前面我們說到Gradle插件其實并沒有提供真正的構建功能, 我們編譯構建的Task很多都是由插件來提供的,如果對這點還不是很了解可以先看下Gradle腳本學習
Java插件
在某種意義上,android插件算是在java插件的基礎上擴展而來的,而java插件也是Gradle官方支持的插件之一,為了讓大家能夠更好的理解Android插件中各個Task的執(zhí)行和依賴關系,我們現對Java插件做一個介紹,英語好的同學可以直接去閱讀Gradle官方The Java Plugin
Java插件的使用很簡單,畢竟是官方支持的
apply plugin: 'java'
這樣就可以了,對于java插件我們主要理解一張Tasks圖表

這里包含了java插件中的絕大部分Tasks,圖標中的Task描述如下
| 名稱 | 依賴 | TaskType | 描述 |
|---|---|---|---|
| compileJava | 所有處理編譯過程的任務 | JavaCompile | 使用javac編譯java源碼 |
| processResources | - | Copy | 把資源文件復制到相應目錄 |
| classes | complileJava和processResources | Task | 生成.class文件和資源文件目錄 |
| compileTestJava | compile,加上編譯測試文件的所有Task | JavaCompile | 使用javac編譯java測試代碼 |
| processTestResources | - | Copy | 把測試資源文件復制到相應目錄 |
| testClasses | compileTestJava和processTestResources | Task | 申城測試的.class文件和資源文件目錄 |
| jar | compile | Jar | 生產jar文件 |
| javadoc | compile | Javadoc | 使用javadoc生產Api文檔 |
| test | compile | Test | 使用JUnit或TestNG運行單元測試 |
| uploadArchives | 生成所有archives需要的artifacts文件的Task,包括jar | Upload | 使用archives配置上傳artifacts包括jar文件 |
| assemble | 項目中的所有archive任務,包括jar | Task | 生成項目所有的archive文件 |
| check | 項目中的所有驗證任務,包括test | Task | 執(zhí)行所有項目中的驗證任務 |
| build | assemble和check | Task | 執(zhí)行完整的項目構建 |
| clean | - | Delete | 刪除項目構建過程生成的文件目錄 |
| clean TaskName | - | Delete | 刪除指定任務創(chuàng)建的文件。 cleanJar將刪除由jar任務創(chuàng)建的JAR文件,cleanTest將刪除測試任務創(chuàng)建的文件 |
我們平時使用當然不可能一步步去編譯,往往只會使用幾個相對簡單的命令,比如check、assemable之類的,但是如果我們對整個build的流程不了解,我們就很難在構建過程中對某一個具體的行為進行優(yōu)化,這里先講解java插件,是因為java的構建過程相對簡明,Android工程的構建過程就相對復雜很多,但是本質上都差不多,建議大家還是可以先學習下
Android插件
Android插件是由google提供,用于配置、編譯、打包android工程,它提供了一些新的DSL和task供我們配置,執(zhí)行android工程的編譯打包過程,關于android插件的使用個人建議可以看下Google提供的GradlePluginUserGuide和AndroidPluginDSL,這里我就算是拋磚引玉了
基本配置
android下最基本的配置很簡單,完成最基本的配置之后Gradle就能夠對我們的project進行構建,同時還有一些的零碎的配置,我也一并并在這里進行說明最最簡單的,我們只需要配置compileSdkVersion和buildtoolsVersion
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
}
這樣就可以完成構建,當然我們還需要配置一些Apk的基本信息,這些信息主要通過defaultConfig{}來進行配置,主要的信息如下
minSdkVersiontargetSdkVersionversionCodeversionNameapplicationId-
testApplicationId(used by the test APK) testInstrumentationRunner
前四條都是一些基本的版本配置信息其中值得一提的是applicationId 這條屬性,形式上和packageName是一致的,當我們使用AndroidStudio創(chuàng)建工程是,applicationId默認是和packageName一樣,但是這兩者是有本質區(qū)別的,packageName是可以改變的,但是applicationId一旦應用發(fā)布就不能修改了,applicationId是APK的標識,同時不同渠道版本的applicationId最好也進行不同的配置,這個稍后進行詳細說明
關于test的配置信息,也會在后面的章節(jié)詳細說明
sourceSets
資源目錄Android插件的默認資源目錄如下
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本質上就是一個配置信息,Android插件提供的dependencies主要有:
- compile: main application
- androidTestCompile: test application
- debugCompile: debug Build Type
- releaseCompile: release Build Type
- testComplie:上面四種是google官方文檔上寫的,事實上testComplie這種純java的test配置也是支持的
根據版本變種,android插件也會生成不同的dependencies,就像android自帶的兩種buildtype就生成了上面兩種dependencies
Android Tasks
前面在gradle我們說到,在gradle中實際的執(zhí)行是通過Task來進行的,Android插件能夠對我們的Project進行構建,必然也提供了相應的Task才能完成構建,我們主要要用到的主要有下面幾個
- assemble生成輸出,會執(zhí)行構建過程
- check運行所有檢查任務
- connectedCheck運行檢查連接的設備或模擬器,所有連接的設備將并行運行。
- deviceCheck使用API??運行檢查以連接到遠程設備,這在CI服務器上使用。
- build這個任務會運行assemble和check。
- clean此任務清除項目的輸出。
感覺和java插件大體相似,只是多了兩個類似設備檢查之類的task,但是事實上,android工程的構建過程還是比較復雜的,所以android插件并沒有給出構建過程中具體的tasks,以及task間的依賴關系,更沒有java插件中提供的task依賴表。
那么我們要怎么才能弄清android構建的具體過程呢,這里我為大家介紹一個插件Inspector,具體使用方法參考GitHub:https://github.com/jakeouellette/inspector,我就不多做介紹,這個插件可以生成我們所運行的task的依賴關系圖,方便大家理解學習。
注意:Inspector不支持windows!不支持windows!不支持windows!
版本變種的配置
BuildType配置
版本變種中有兩個內容,BuildType和ProductFlavor,首先是關于BuildType,Android插件默認提供debug和release兩種BuildType,當然我們也可以自己添加新的BuildType,Android下對于每一種BuildType都可以有各自的配置信息,同時可以根據配置信息生成獨特apk,首先對于不同的BuildType,我們會有不同的dependencies配置compile類型,就像上面 dubugCompile一樣,類似下面的代碼
android {
buildTypes {
jnidebug {
}
}
}
就會生成一個jnidebugCompile,前面我們說過aseemble這個task可以生產所有的輸出,這里我們有三個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唯一標識,每次調用都是在最開始的applicationId上添加
debuggable|Boolean|調試開關
consumerProguardFiles|List<File>|生成的aar文件中的混淆規(guī)則,只針對Library工程
jniDebuggable|Boolean|jniDebug開關
minifyEnabled|Boolean|混淆開關
signingConfig|SigningConfig|簽名配置
proguardFiles|List<File>|生成apk時使用的混淆配置文件
shrinkResources|Boolean|移除沒有用到的資源文件,默認為false
embedMicroApp|Boolean|Android Wear app是否需要嵌入此build type
manifestPlaceholders|Map<String, Object>|配置manifest屬性,合并時使用這里的屬性
multiDexEnabled|Boolean|Multi-Dex開關
multiDexKeepFile|File|main dex的配置文件,text文件,每行指定一個class文件,格式為com/example/MyClass.class
multiDexKeepProguard|File|main dex的混淆規(guī)則,會和構建系統的混淆規(guī)則合并
zipAlignEnabled|Boolean|壓縮對齊開關
[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|復制所有屬性
SigningConfig
Android 要求所有 APK 必須先使用證書進行數字簽署,然后才能安裝。Android插件已經幫我們配置了兩種BuildType:debug和release,其中debug默認使用Android自動生成的dubug Signing,而release默認是沒有配置Signing的,我們可以直接在代碼中進行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配置中的常量默認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基本類似,同時也會生成相應的Task和Compile,主要區(qū)別就是BuildType的分類是針對開發(fā)者的,如debug、release,而ProductFlavor的分類是針對用戶的,如free、pay,所以可配置的內容是不同的,ProductFlavor的配置信息主要如下:
名稱|類型|說明
---|--|--|--
applicationId|String|-
applicationIdSuffix|String|為 applicationId添加后綴,applicationId是app唯一標識,每次調用都是在最開始的applicationId上添加
consumerProguardFiles|List<File>|生成的aar文件中的混淆規(guī)則,只針對Library工程
dimension|String|此flavor的dimensioin類型
externalNativeBuild|ExternalNativeBuildOptions|封裝了native相關構建的信息
jackOptions|JackOptions|jack配置
signingConfig|SigningConfig|簽名配置
proguardFiles|List<File>|生成apk時使用的混淆配置文件
manifestPlaceholders|Map<String, Object>|配置manifest屬性,合并時使用這里的屬性
multiDexEnabled|Boolean|Multi-Dex開關
multiDexKeepFile|File|main dex的配置文件,text文件,每行指定一個class文件,格式為com/example/MyClass.class
multiDexKeepProguard|File|main dex的混淆規(guī)則,會和構建系統的混淆規(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|設置flavor最高sdk版本
minSdkVersion(int or String)|Method|設置flavor最低sdk版本
Build Variant
我們知道一種BuildType會生產一種Apk,ProductFlavor也是一樣的,那個一個工程可以產出的不同種類的apk將是這兩者的合并,比如一個有兩個Flavor的工程,加上默認的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/
如果出現同名的文件那么他們的優(yōu)先級順序是flavor1Debug>debug>flavor1>main,一層會覆蓋一層。對于Dependencies,這個規(guī)則也是一樣的。
小結
Android插件的內容并不算多,但是想要用好Gradle,我們除了要了解這些東西之外,還需要了解Gradle和Groovy提供的API以及一些其他的插件才能更好的使用它。