[Android] 配置build.gradle 動態傳參

(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部分。

相關文章
相關標籤/搜索