(1)一個Android工程中有一個build.gradle是負責Project範圍的,而Module中又有各自的build.gradle是專門負責模塊的。android
(2)在Gradle中Task是一等公民,經過gradlew + task名 能夠直接執行指定Task,例以下面的命令就是執行:task releaseAutoBLForAarapi
gradlew releaseAutoBLForAar
(3)在defaultConfig中能夠自定義變量名,編譯時能夠在Java代碼中引用到:app
defaultConfig { applicationId "com.test" minSdkVersion 15 targetSdkVersion 23 versionCode 5 versionName 1.1.0 buildConfigField("String", "API_HOST", "${API_DEV_HOST}") }
這裏面的API_HOST是String型的(第三個參數是表示傳值),能夠看到Java代碼生成,這樣就能創建起代碼與配置之間的橋樑:測試
public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "com.test"; public static final String BUILD_TYPE = "debug"; public static final int VERSION_CODE = 6; public static final String VERSION_NAME = "1.1.1"; // Fields from default config. public static final String API_HOST = "http://test.api.cn"; }
(4)經過 buildTypes 能夠配置不一樣的任務參數gradle
buildTypes { release { /* 線上環境 */ buildConfigField "boolean", "LOG_DEBUG", "false" // 不顯示Log buildConfigField "String", "API_HOST", "${API_RELEASE_HOST}" //API Host minifyEnabled true //是否混淆 zipAlignEnabled true //是否設置zip對齊優化 shrinkResources true // 移除無用的resource文件 signingConfig signingConfigs.release //簽名 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } preRelease { /* 預發環境 */ buildConfigField "boolean", "LOG_DEBUG", "false" // 不顯示Log // 。。。 } debug { /* 本地開發環境 */ minifyEnabled false } beta { /* 測試環境 */ buildConfigField "boolean", "LOG_DEBUG", "true" // 顯示Log // 。。。 } }
能夠經過AndroidStudio的Gradle面板看到多個編譯任務,原來默認只有assembleDebug,如今就多了assembleBeta、assemblePreRelease、assembleRelease,雙擊便可執行。優化
(5)如何經過Gradle動態配置不一樣的AndroidManifest.xml 變量內容呢?經過自定義manifestPlaceholders 屬性值。ui
首先在AndroidManifest.xml 文件中指定要使用Gradle動態配置值${TALKING_DATA_APP_ID}:google
<!--TalkingData 配置--> <meta-data android:name="TD_APP_ID" android:value="${TALKING_DATA_APP_ID}" />
能夠在build.gradle中配置一個特別的變量屬性:spa
def TEST_TALKING_DATA_APP_ID = "6E5389EAD0C2C2CFB7B379701F6D2BA8" defaultConfig { applicationId "com.test" minSdkVersion 15 targetSdkVersion 23 versionCode 5 versionName 1.1.0 buildConfigField("String", "API_HOST", "${API_DEV_HOST}") manifestPlaceholders = [ /* talkingData 測試環境 */ TALKING_DATA_APP_ID: "${TEST_TALKING_DATA_APP_ID}" /* 能夠新增多個鍵值對,表示變量與對應的值 */ ] }
同理,咱們能夠在buildTypes中分別指定release、debug等配置的manifestPlaceholders 來達到不一樣的配置效果。 debug
(6)如何在build.gradle中動態獲取參數選項?經過 project.hasProperty('VERSION_CODE') 的形式來獲取動態傳參。
defaultConfig { applicationId "com.ixwork" minSdkVersion 15 targetSdkVersion 23 //關鍵看這兩行 versionCode project.hasProperty('VERSION_CODE') ? Integer.parseInt(VERSION_CODE) : DEF_VERSION_CODE versionName project.hasProperty('VERSION_NAME') ? VERSION_NAME : "${DEF_VERSION_NAME}" buildConfigField("String", "API_HOST", "${API_DEV_HOST}") }
(7)怎麼傳參呢?經過-PVAR_NAME=VAR_VALUE 的形式,其中-P就是加參數,例如:
gradle clean assembleBeta -PVERSION_CODE=5 -PVERSION_NAME=1.1.1 -POUT_PUT_DIR=/home/user/Desktop -PFILE_NAME=test.apk
// 這裏面一個小細節很重要,執行gradle任務時以前加一個clean清除一下結果,能夠有效防止編譯過程當中誤報錯誤。好比關閉了某個宏致使某些class文件再也不被編譯,可是可能因爲舊的信息殘留致使報錯提示找不到class
(8)怎麼設置APP工程使用一個aar庫呢?兩步走:(1)設置本地倉庫地址;(2)設置依賴文件名稱和擴展名。
dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' // implementation project(':testjni') // 這一句是用來設置工程依賴的,若是設置了直接依賴那麼就比如就是同一個工程內了,直接import類使用便可 compile (name:'testjni-debug', ext:'aar') // 這一句是用來設置工程依賴某個具體aar包的,name字段填寫包名,ext字段填寫擴展名 }
若是是初始工程這麼設置一下的話,編譯會報錯說找不到這個testjni-debug.arr,緣由是存放這個文件的「倉庫」路徑並無被加入到工程內,須要咱們設置一下倉庫地址(假設存在aar文件的路徑是app/libs目錄):
allprojects { repositories { google() jcenter() flatDir {dirs '../app/libs'} // 在整個工程的build.gradle 中倉庫配置此字段 } }
(9)怎麼理解一個task的內容?舉幾個很實用的小例子來看看:
task clearOutput(type:Delete){ // 刪除任務,內容就是刪除兩個目錄 delete 'build_output' delete '../app/libs' } task taskJar(type:Jar, dependsOn:"assembleRelease" ) { // 這個Jar包的任務依賴於assembleRelease(系統的Release配置任務)意思就是至關於執行這個任務了,而且還附加了下面的邏輯步驟 from 'build/intermediates/classes/release/' // 源路徑 destinationDir = file('build_output/libs') // 目標路徑 } task releaseOutput(type:Copy, dependsOn: [clearOutput, taskJar]) { // 依賴於兩個任務,至關於要依次執行完這兩個任務,以後再拷貝文件(文件列表以下描述) from('libs') { include '*.jar','armeabi-v7a/lib*.so' } into ('build_output/libs') } task releaseOutputAar(type:Copy, dependsOn:[clearOutput, "assembleRelease"]){ // 依賴於兩個任務,以後拷貝,拷貝的目標能夠是多個,連續執行 from('build/outputs/aar') { include 'testjni-release.aar' } into ('build_output') into ('../app/libs') }
(10)【坑】有一點要理解深刻點:一旦配置了externalNativeBuild,那麼執行以及依賴assembRelease/Debug的任務可就都會編譯打包so了!不配置就只會編譯打包Java部分。