config.gradle
文件ext {
android = [
compileSdkVersion: 23,
buildToolsVersion: "23.0.3",
applicationId: "com.example.lizejun.repogradle",
minSdkVersion: 14,
targetSdkVersion: 23,
versionCode: 1,
versionName: "1.0",
testInstrumentationRunner: "android.support.test.runner.AndroidJUnitRunner"
]
dependencies = [
"support-v4" : 'com.android.support:support-v4:23.2.0',
"support-v7" : 'com.android.support:appcompat-v7:23.2.0'
]
}
複製代碼
android
用來管理SDK
版本、版本號等,dependencies
用來管理依賴庫的版本,它們都是一個數組,用逗號來分割,數組的每一個元素都是key:value
的格式。java
build.gradle
,新增:apply from: "config.gradle"
複製代碼
Module
或者Library
中的build.gradle
文件中,引用對應的key
:android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
applicationId rootProject.ext.android.applicationId
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
}
}
dependencies {
compile rootProject.ext.dependencies["support-v7"]
}
複製代碼
依賴樹的查看能夠經過Android Studio
的插件Gradle View
來查看: android
View -> Tool Windows -> Gradle View
,以後會在最下方生成一個窗口,咱們經過這個窗口就能夠看到對應項目的依賴關係:
除此以外,咱們也可使用如下的命令:windows
./gradlew -q app:dependencies
複製代碼
一樣能夠得到相似的結果: api
(*)
,那麼表示這個依賴被忽略了,這是由於其餘頂級依賴中也依賴了這個傳遞的依賴,
Gradle
會自動分析下載最合適的依賴。
因爲多個頂級依賴當中,可能包含了相同的子依賴,可是它們的版本不一樣,這時候爲了選擇合適的版本,那麼就須要使用一些必要的操做符來管理子依賴。數組
Transitive
默認爲true
,表示gradle
自動添加子依賴項,造成一個多層樹形結構;設置爲false
,則須要手動添加每一個依賴項。bash
Transitive
configurations.all {
transitive = false
}
dependencies {
compile rootProject.ext.dependencies["support-v7"]
}
複製代碼
最終獲得的結果是,能夠看到前面的子依賴項都沒有了: app
Transitive
dependencies {
compile ('com.android.support:appcompat-v7:23.2.0') {
transitive = false
}
}
複製代碼
Force
用來表示強制設置某個模塊的版本:maven
configurations.all {
resolutionStrategy {
force 'com.android.support:support-v4:23.1.0'
}
}
複製代碼
以後打印,發現其依賴的包版本變成了23.1.0
: ide
exclude
該標識符用來設置不編譯指定的模塊工具
configurations {
all *.exclude group : 'com.android.support', module: 'support-v4'
}
複製代碼
此時的依賴關係爲:
exclude
後的參數有
group
和
module
,能夠分別單獨使用,會排除全部匹配項。
exclude
compile ('com.android.support:appcompat-v7:23.2.0') {
exclude group : 'com.android.support', module: 'support-v4'
}
複製代碼
也會和上面得到相同的結果
同一配置下,某個模塊的不一樣版本同時被依賴時,默認使用最新版,Gradle
同步時不會報錯。
Gradle
詳解基本配置:AS
中的Android
項目一般至少包含兩個build.gradle
,一個是Project
範圍的,另外一個是Module
範圍的,因爲一個Project
能夠有多個Module
,因此每一個Module
下都會對應一個build.gradle
。
Project
下的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle"
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
複製代碼
buildscript
下的repositories
是gradle
腳本自身須要的資源,allprojects
下的repositories
是項目全部模塊須要的資源。build.gradle
//聲明插件,代表這是一個Android程序;若是是庫,那麼應當是com.android.library
apply plugin: 'com.android.application'
//Android構建過程須要配置的參數
android {
//編譯版本
compileSdkVersion rootProject.ext.android.compileSdkVersion
//buildTool版本
buildToolsVersion rootProject.ext.android.buildToolsVersion
//默認配置,同時應用到debug和release版本上
defaultConfig {
applicationId rootProject.ext.android.applicationId
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
}
//配置debug和release版本的一些參數,例如混淆,簽名配置等
buildTypes {
//release版本
release {
minifyEnabled false //是否開啓混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //混淆文件位置
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile rootProject.ext.dependencies["support-v7"]
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
}
複製代碼
下面對Android
構建過程當中須要配置的參數作一些解釋:
compileSdkVersion
:告訴gradle
用那個Android SDK
的版本編譯你的應用,修改它不會改變運行時的行爲,由於它不會被包含進入最終的APK
中;所以,推薦使用最新的SDK
編譯;若是使用Suppport Library
,那麼compileSdkVersion
必需要大於等於它的大版本號。minSdkVersion
:應用最低可運行的要求;它必需要大於等於你所依賴的庫的minSdkVersion
;targetSdkVersion
:Android
提供向前兼容的重要依據。(targetSdkVersion is the main way Android provides forward compatibility
) 由於隨着Android
系統的升級,某個api
或者模塊的行爲有可能發生改變,可是爲了保證老APK
的行爲和之前兼容,只要APK
的targetSdkVersion
不變,那麼即便這個APK
安裝在新的Android
系統上,那麼行爲仍是保持老的系統上的行爲。 系統在調用某個api
或者模塊的時候,會先檢查調用的APK
的targetSdkVersion
,來決定執行什麼行爲。minSdkVersion
和targetSdkVersion
最終會被包含進入最終的APK
文件中,若是你查看生成的AndroidManifest.xml
,那麼會發現:
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="7" />
複製代碼
因此,咱們通常遵循的規則是:
minSdkVersion (lowest possible) <= targetSdkVersion == compileSdkVersion (latest SDK)
複製代碼
gradle
相關文件gradle.properties
配置文件,能夠定義一些常量供build.gradle
使用,好比能夠配置簽名相關信息,例如keystore
位置、密碼、keyalias
等。settings.gradle
用來配置多模塊的,若是你的項目有兩個模塊Browser
和ScannerSDK
,那麼就須要:include ':Browser'
include ':ScannerSDK'
project(':ScannerSDK').projectDir = new File(settingsDir, './ScannerSDK/')
複製代碼
gradle
文件夾 裏面有兩個文件,gradle-wrapper.jar
和gradle-wrapper.properties
,後者當中指定了gradle
的版本。distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
複製代碼
gradlew
和gradlew.bat
分別是Linux
和windows
下的批處理文件,它們的做用是根據gradle-wrapper.properties
文件中的distributionUrl
下載對應的gradle
版本,這樣即便環境沒有安裝gradle
也能夠編譯。gradle
倉庫gradle
有三種倉庫:maven/ivy/flat本地
。
maven{
url "..."
}
ivy{
url "..."
}
flatDir{
dirs 'xxx'
}
複製代碼
有些倉庫取了別名:
repositories{
mavenCentral()
jcenter()
mavenLocal()
}
複製代碼
gradle
任務經過如下指令,能夠看到支持的任務:
./gradlew tasks
複製代碼
Jar
包導入單個jar
文件:
compile files('libs/xxx.jar')
複製代碼
導入libs
的多個jar
文件:
compile fileTree(dir: 'libs', include: ['*.jar'])
複製代碼
maven
庫compile 'groupId:artifactId:version'
複製代碼
Project
在導入以前,須要在settings.gradle
中把模塊包含進來,例如前面的ScannerSDK
模塊:
compile project(':ScannerSDK')
複製代碼
maven
庫若是項目中須要的一些庫文件再也不中央倉庫中,而是在某個特定地址裏,那麼就須要在Project
中的build.gradle
中的allprojects
結點下或者直接配到某個模塊中:
allprojects {
repositories {
maven {
url '地址'
}
}
}
複製代碼
aar
compile 'com.aaa.xxx:core:1.0.1@aar'
複製代碼
aar
首先,你的項目必須是一個庫項目,以後在build.gradle
中進行配置:
apply plugin : 'com.android.library'
複製代碼
以後,進入到該項目中,執行gradle
命令:
./gradlew assembleRelease
複製代碼
生成的aar
放在/build/output/aar
文件當中
aar
首先,將aar
文件拷貝到對應目錄下,而後在該模塊的build.gradle
中聲明flat
倉庫:
repositories{
flatDir{
dirs '以build.gradle爲根目錄的相對路徑'
}
}
複製代碼
以後,在dependencies
結點下依賴該aar
模塊:
dependencies{
compile (name:'xxx',ext:'aar')
}
複製代碼
在此以前,咱們先了解幾個基本的概念:
buildTypes
:構建類型,Android Studio
的Gradle
組件默認提供了debug
和release
兩個默認配置,這裏主要用因而否須要混淆,是否調試。productFlavors
:產品渠道,在實際發佈中,根據不一樣渠道,可能須要使用不一樣的包名,甚至是不一樣的代碼。buildVaiants
:每一個buildTypes
和productFlavors
組成一個buildvariant
。以上咱們討論的buildTypes
和productFlavors
能夠經過每一個Module
中的build.gradle
的android
標籤來配置。
下面,咱們先看一下不一樣的productFlavors
,分別用來支持讀取不一樣的文件和替換不一樣的字符串。
咱們首先在app/src
目錄下新建兩個目錄,分別對應兩個Flavor
,再在其中創建相同名字的文件Constant.java
,對裏面的某個常量賦予不一樣的值。
constantFlavor1
:package com.example.lizejun.repogradle;
public class Constant {
public static final String NAME = "flavor1";
}
複製代碼
constantFlavor2
:package com.example.lizejun.repogradle;
public class Constant {
public static final String NAME = "flavor2";
}
複製代碼
咱們的app
下的build.gradle
中的android
標籤下添加以下幾行代碼,讓兩個Flavor
分別引用不一樣的Constant
文件:
sourceSets {
constantFlavor1 {
java.srcDirs = ['src/constantFlavor1', 'src/constantFlavor1/java', 'src/constantFlavor1/java/']
}
constantFlavor2 {
java.srcDirs = ['src/constantFlavor2', 'src/constantFlavor2/java', 'src/constantFlavor2/java/']
}
}
productFlavors {
constantFlavor1 {}
constantFlavor2 {}
}
複製代碼
以後咱們進行打包,能夠獲得如下不一樣安裝包,這兩個apk
若是在其中引用的了NAME
,那麼它會獲得不一樣的值:
buildConfig
類若是咱們只須要定義一些簡單的值,那麼咱們能夠用buildConfig
類:
productFlavors {
constantFlavor1 {
buildConfigField "boolean", "BOOLEAN_VALUE", "true"
}
constantFlavor2 {
buildConfigField "boolean", "BOOLEAN_VALUE", "false"
}
}
複製代碼
productFlavors {
constantFlavor1 {
buildConfigField "boolean", "BOOLEAN_VALUE", "true"
manifestPlaceholders = [label:"constantFlavor1"]
}
constantFlavor2 {
buildConfigField "boolean", "BOOLEAN_VALUE", "false"
manifestPlaceholders = [label:"constantFlavor2"]
}
}
複製代碼
以後,咱們再在AndroidManifest.xml
中引用它:
android:label="${label}"
複製代碼
首先是在android
標籤下,咱們使用signingConfigs
來配置不一樣的簽名類型
signingConfigs {
eng {
keyAlias 'androiddebugkey'
keyPassword 'android'
storeFile file('debug.keystore')
storePassword 'android'
}
prd {
keyAlias 'androiddebugkey'
keyPassword 'android'
storeFile file('debug.keystore')
storePassword 'android'
}
}
複製代碼
以後,再在buildTypes
的各個分支中引用對應的簽名配置:
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.eng
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.prd
}
}
複製代碼
有時候,咱們須要在不一樣的buildTypes
下,引用不一樣的依賴,例如內存泄露的檢測工具,咱們但願在debug
版本時檢查內存泄露,並在發生時在桌面上生成圖標,可是在release
版本上咱們並不但願這麼作,這時候咱們能夠這麼寫:
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
複製代碼
這樣,release
版本就不會在桌面生成內存泄露的圖標。