一拇舀、多工程配置
Gradle工程可以通過多工程配置來依賴其他的Gradle工程。
多工程配置通常把所有的工程作為"根目錄的子文件夾"蜻底;
比如下面的工程:
MyProject/
app/
libraries/
lib1/
lib2/
我們可以識別這三個工程骄崩。Gradle會通過如下名字引用它們:
:app
:libraries:lib1
:libraries:lib2
每個工程都有自己的build.gradle文件來定義如何構(gòu)建自己。
此外薄辅,工程的根目錄中有個settings.gradle的文件要拂,會定義所有的工程;
文件目錄結(jié)構(gòu)如下:
MyProject/
settings.gradle
app/
build.gradle
libraries/
lib1/
build.gradle
lib2/
build.gradle
settings.gradle文件中的配置如下:
include ':app',':libraries:lib1',':libraries:lib2'
這里定義了哪些文件是一個Gradle工程站楚;
:app工程也可能會依賴一些庫工程脱惰,可以通過如下腳本聲明依賴:
dependencies { compile projects(':libraries:lib1') }
二、庫工程
- 普通工程和庫工程的不同:
庫工程的main輸出的是一個.aar包窿春,它由編譯后的代碼(比如jar文件或者.so文件)以及資源文件(manifest拉一,res,assets)組成旧乞。 庫工程也可以生成一個測試apk蔚润,可以獨立于應(yīng)用進(jìn)行測試。
它有相同的引導(dǎo)任務(wù)( assembleDebug , assembleRelease )尺栖,所以他和一般的工程沒有什么不同嫡纠。
其余的,基本上都和應(yīng)用一樣了。他們都有build types和product flavors除盏,可以生成多個版本的aar叉橱。 注意 Build Type 大部分配置并不適用于庫工程。不過你可以依據(jù)庫工程是被其他工程依賴還是測試痴颊,然后通過自定義庫工程 sourceSet 改變它的內(nèi)容赏迟。 - 庫工程的發(fā)布
默認(rèn)情況下庫工程只能發(fā)布release版本。這個版本用于所有工程的引用蠢棱,和工程要構(gòu)建什么樣的版本無關(guān)--這是屬于Gradle的限制锌杀;
三、根目錄的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
//buildscripe{...}這部分用來配置驅(qū)動構(gòu)建的代碼
//這部分配置只會影響構(gòu)建過程泻仙,和工程沒有關(guān)系糕再;工程會定義它自己的倉庫和相關(guān)依賴
buildscript {
//配置使用什么倉庫
repositories {
//指定倉庫URL快捷方式
jcenter()
}
//配置 依賴什么插件
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
/**
* 設(shè)置全局參數(shù)
* 可以在app/build.gradle中使用:
* compileSdkVersion rootProject.ext.compileSdkVersion
* buildToolsVersion rootProject.ext.buildToolsVersion
*/
ext {
compileSdkVersion = 26
buildToolsVersion = "26.0.2"
}
五、app下面的build.gradle
//配置應(yīng)用android插件玉转;
//備注:只應(yīng)用android插件就好了突想,不要同時應(yīng)用java插件,因為這會導(dǎo)致構(gòu)建錯誤
apply plugin: 'com.android.application'
import com.android.build.OutputFile
//可以從文件中讀取版本名字或者使用一些其他的自定義邏輯
def computeVersionName(){
"1.0.2"http://不用寫return 默認(rèn)最后一行就是返回值
}
//配置了android構(gòu)建需要的所有參數(shù)究抓,默認(rèn)情況下只有編譯sdk的版本(compileSDKVersion)猾担、構(gòu)建工具版本(buildToolsVersion)是必須的;
//android 元素里的 defaultConfig 負(fù)責(zé)定義所有的配置刺下。
android {
//使用全局配置--配置見project/build.gradle
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "com.zcbl.client.zcblsdk"
minSdkVersion 23
targetSdkVersion 26
versionCode 1
versionName computeVersionName()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk{
//生成.so的名字
moduleName "hello"
}
// multiDexEnabled true
}
/**
* 這前用上面multiDexEnabled true時绑嘹,
* 突然在5.0以下的手機上跑不起來,
* 改成下面這種寫法就可以了橘茉。
*/
dexOptions {
jumboMode true
}
buildTypes {
release {
minifyEnabled false
//有兩個默認(rèn)的規(guī)則文件
//1.proguard-android.txt
//2.proguard-android-optimize.txt
//它們都位于SDK中工腋,使用getDefaultProguardFile()方法可以返回文件的全路徑。二者除了是否開啟優(yōu)化之外畅卓,其他功能全相同擅腰;
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// 構(gòu)建類型是否應(yīng)該生成可調(diào)試的apk
// debuggable true
}
debug {
//配置了默認(rèn)debug的構(gòu)建類型:設(shè)置包名以.debug為后綴,這樣和release的包名不一致了翁潘,就能在同一個設(shè)備上\
// 同時安裝debug和release兩個版本的APK
applicationIdSuffix ".debug"
//構(gòu)建類型是否配置為使用可調(diào)試的本機代碼生成APK
// jniDebuggable true
//注意:使用此配置趁冈,需要注釋點res/strings/中的app_name ,用來動態(tài)配置不同app的名字
// resValue('string','app_name','測試版')
}
//創(chuàng)建一個buildTypes很簡單拜马,只需要在buildTypes容器中添加一個元素箱歧,然后調(diào)用initWith()或者使用一個閉包配置它;
//initWith所傳的參數(shù)是為了配置作為哪個(release或者debug)的副本一膨,也就說打出來的包用什么證書簽名;
//如果不傳參數(shù)洒沦,將會打出一個沒有被簽名的apk文件
jnidebug.initWith(buildTypes.debug)
jnidebug {
applicationIdSuffix ".jnidebug"
// packageNameSuffix ".jnidebug"http://decorated
jniDebuggable true
versionNameSuffix ".debug"
// signingConfig
// proguardFile
// proguardFiles
// minifyEnabled
// zipAlignEnabled
// debuggable
// jniDebuggable
// renderscriptDebuggable
// renderscriptOptimLevel
// manifestPlaceholders = [PGY_PGYER_APPID:"********"]
// buildConfigField('String','API_URL','\"http://www.baidu.com\"')
}
}
//通常情況下豹绪,Build Type 配置會覆蓋其他配置,比如,Build Type 的 packageNameSuffix 會追加到 Product Flavor 的 packageName 之后瞒津。
//也有一些情況是在 Build Type 和 Product Flavor 中都可以設(shè)置蝉衣,在這種情況下,視情況而定巷蚪。
//比如病毡, signingConfig 就是這么一個屬性。 通過設(shè)置 android.buildTypes.release.signingConfig 屁柏,可以為所
// 有的release包共享相同的SigningConfig啦膜,也可以單獨通過設(shè)置android.productFlavors.*.signingConfig為每
// 一個release包指定他們自己的 SigningConfig 。
/**
* //指定兩個維度:是否付費和發(fā)布的平臺
* flavorDimensions中定義的Dimensions排序很重要:這個排序決定了哪一個flavor中設(shè)置的屬性覆蓋哪一個淌喻,因為一個flavor中的
* 值(設(shè)置的屬性)會被替換定義在底優(yōu)先級的flavor中的值(屬性)僧家;比如下面"發(fā)布平臺(store)"中設(shè)置的versionName會
* 覆蓋"是否付費(price)"中設(shè)置的versionName,也就是打出的包的versionName對應(yīng)為:google,amazon,baidu;
* 但高優(yōu)先級的會覆蓋低優(yōu)先級的資源--也就是res目錄下的資源文件會遵循優(yōu)先級覆蓋的原則裸删;
*/
flavorDimensions "price","store"
//android.productFlavors.*是ProductFlavor類型的八拱,和android.defaultConfig對象具有相同的類型,這就意味著他們有相同的屬性涯塔;
//defalutConfig為所有的flavor提供了基本的配置肌稻,每一個falvor也都可以重新設(shè)置覆蓋這些默認(rèn)值;
productFlavors{
//favours的名字不能和Build Types 名字或者androidTest SourceSet沖突
//每一個favours都可以通過一個閉包單獨設(shè)置
google{
versionName 'google'
dimension "store"
}
amazon{
versionName 'amazon'
dimension "store"
// manifestPlaceholders = [PGY_PGYER_APPID:"********"]
buildConfigField 'String','API_URL','\"API_URL_FLAVOR2\"'
buildConfigField("boolean","LOG_DEBUG","false")
}
baidu{
versionName 'baidu'
dimension 'store'
}
free{
versionName 'free'
dimension 'price'
}
paid{
versionName 'paid'
dimension 'price'
}
// //下面的只有沒有設(shè)置flavorDimensions時才能編譯通過
// tx{
// versionName 'tx'
// }
}
sourceSets {
// main {
// //修改項目目錄:使用場景-->就是eclipse項目轉(zhuǎn)Android studio項目匕荸,需要重新配置項目結(jié)構(gòu)
// //要替換默認(rèn)的源文件夾的話爹谭,可以給 srcDirs 指定一個路徑數(shù)組
// manifest.srcFile 'AndroidManifest.xml'
// java.srcDirs = ['src']
// resources.srcDirs = ['src']
// aidl.srcDirs = ['src']
// renderscript.srcDirs = ['src']
// res.srcDirs = ['res']
// assets.srcDirs = ['assets']
// }
//不同產(chǎn)品不同的文件
// falvor1 {
// java.srcDirs = ['src/product/java']
// }
// falvor2 {
// java.srcDirs = ['src/temp/java']
// }
}
// //注意:srcDir 會添加指定的文件夾到現(xiàn)有的源文件夾列表中(Gradle文檔沒有提到這個,但是的確是這樣的)
//當(dāng)默認(rèn)的工程結(jié)構(gòu)不適用的時候每聪,你可能需要配置它旦棉。根據(jù)Gradle文檔說明,可以通過如下方式重新配置Java工程的 sourceSets:
// sourceSets {
// main {
// java {
// srcDir 'src/java' // 指定源碼目錄
// }
// resources {
// srcDir 'src/resources'//資源目錄
// }
// assets {
// srcDir 'src/assets'
// }
// }
// }
/**
* 主要用來配置打包時药薯,來從哪里打包資源或者代碼
* 說白了 就是告訴編譯器你從哪個文件下找出代碼绑洛,打包進(jìn)apk文件里
*/
// sourceSets {
// main() {
// jniLibs.srcDirs = ['src/main/libs']
// jni.srcDirs = []
// }
// }
/**
* 一般應(yīng)該盡可能的建立一個單一的apk,這個apk可以支持所有的目標(biāo)設(shè)備童本,但是這會導(dǎo)致一個apk包體積非常大真屯;因為這個apk
* 支持所有"屏幕密度"或"應(yīng)用二進(jìn)制接口"(ABI).
* 減少apk體積的一種方法,就是創(chuàng)建支持特定屏幕密度或者abi的apk穷娱。
*
* Gradle可以使用splits來進(jìn)行apk拆分:
* 需要在splits{}中添加density{}或者abi{}閉包函數(shù)绑蔫;
* 參數(shù)說明:
* enable:如果為true,Gradle會根據(jù)定義的屏幕密度或者abi來生成指定屏幕密度或者abi的apk包泵额;默認(rèn)為false配深;
* exclude:用來排除應(yīng)用不需要支持的屏幕密度或者abi,支持的類型一般用逗號分隔嫁盲;
* include:與exclude對應(yīng)篓叶,只能與reset()結(jié)合使用才能指定支持的屏幕密度或者abi;支持的類型一般用逗號分隔;
* reset():清除默認(rèn)支持的屏幕密度或abi缸托。注意:這個方法僅當(dāng)與include元素組合使用時才能添加指定的屏幕密度或者abi左敌;
* 比如設(shè)置支持密度為ldpi和xxhdpi的設(shè)置如下:
* splits{
* //density提供所需的屏幕密度和兼容的屏幕尺寸的列表
* density{
* reset()
* include "ldpi","xxhdpi"
* }
* }
*
* compatibleScreens:指定兼容的屏幕尺寸,指定多個尺寸使用逗號分隔俐镐;這將在每個拆分的apk的manifest中注入匹配的<compatible-screens>節(jié)點矫限;
* 這個可選設(shè)置提供了在同一個build.gradle中管理屏幕密度和屏幕大小的方法;但是使用<compatible-screens>將限制應(yīng)用程序使用的設(shè)配類型佩抹;
* universalApk:這個是abi獨有的一個配置叼风;如果為true,Gradle將會生成包含所有abi的通用abi以及拆分的apk匹摇,通用apk中包含所有的abi代碼和資源咬扇;
* 默認(rèn)值為false.
* 密度APK分裂總是生成一個通用的APK,包含所有屏幕密度的代碼和資源廊勃。
*/
// splits{
//
//// density{
//// enable true
//// exclude "ldpi","xxhdpi","xxxhdpi"
//// compatibleScreens 'small','normal','large','xlarge'
//// }
//
// abi{
// enable true
// reset()
// include 'x86','armeabi-v7a'
// universalApk true
// }
// }
// map for the version code
// project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]
//
// // applicationVariants are e.g. debug, release
// applicationVariants.all { variant ->
// variant.outputs.each { output ->
// // For each separate APK per architecture, set a unique version code as described here:
// // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
//// def versionCodes = ["armeabi-v7a": 1, "x86": 2]
//
// def abi = output.getFilter(OutputFile.ABI)
// if (abi != null) { // null for the universal-debug, universal-release variants
// output.versionCodeOverride = project.ext.versionCodes.get(abi) * 100 + defaultConfig.versionCode
// }
// }
// }
}
/**
* 為了打包出不同versionCode值的配置
* 下面的意思:將打出的x86的apk包的versionCode修改為301懈贺,將打出的armeabi-v7a的apk包的versionCode修改為:101
* 同android節(jié)點下的配置效果一樣
*/
project.ext.versionCodes = ['armeabi-v7a':1, mips:2, x86:3]
android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
def abi = output.getFilter(OutputFile.ABI)
if (null != abi) {
output.versionCodeOverride = project.ext.versionCodes.get(abi) * 100 + android.defaultConfig.versionCode
}
}
}
//注:dependencies DSL元素是標(biāo)準(zhǔn)Gradle API的一部分,并不屬于android的元素
dependencies {
//compile 配置用來編譯main application坡垫,它里面的一切都會被添加到編譯的classpath中梭灿,并且也會被打包到最終的apk中
//compile : main application
//androidTestCompile: test application
//debugCompile: debug Build Type
//releaseCompile: release Build Type
//因為要構(gòu)建生成一個APK,必然會有相關(guān)聯(lián)的Build Type,APK默認(rèn)配置兩個(或者更多)編譯配置:compile和<buildtpe>Compile.
//創(chuàng)建一個新的Build Type 的時候會自動創(chuàng)建一個基于它名字的編譯配置;
//當(dāng)一個debug版本需要一個自定義庫(比如報告崩潰)冰悠,但是release版本不需要或者需要一個不同版本的庫的時候堡妒,會顯得非常有用;
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
//配置依賴一個外部庫jar包溉卓,可以在compile配置里添加一個依賴
// compile files('libs/foo.jar')
debugCompile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
//引用一個根目錄下的庫工程方式如下:
// compile project(':libraries:lib1')
//設(shè)置不同的產(chǎn)品引入不同的包
// falvor1Compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
}
////生成arr
//repositories {
// flatDir {
// dirs 'aars'
// }
//}
////使用aar
//dependencies {
// compile(name:'libraryname', ext:'aar')
//}