1. 程式人生 > >Android使用Gradle自動化打包

Android使用Gradle自動化打包

假如我們使用了友盟sdk或者別的sdk,我們需要在androidMainifest 填寫一個渠道號,來幫助我們統計。也就說app釋出之後需要每個應用市場對應著唯一的渠道號。如果我們不使用自動化打包的話,就非常的麻煩,需要自己去改Mainifest.xml中的渠道號。還好,我們可以使用gradle來幫我們完成這個過程。
我目前的一個專案使用了友盟統計,我需要在AndroidMainifest.xml中寫入渠道號

 <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}"
/>

我使用${UMENG_CHANNEL_VALUE} 來代替渠道號,最終中使用gradle會將它替換成真正的渠道號。
我們在app 的build.gradle檔案中android{}中,這樣寫:

  productFlavors {
        wandoujia {
        }
        qihu360 {
        }
        baidu {
        }
        productFlavors.all {
            flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
        }
    }

這樣在打包之後他就會使用 wandoujia ,qihu360,baidu來替換UMENG_CHANNEL_VALUE 完成渠道號的填寫
然後我們在命令列輸入 gradle assemble 來完成打包。
如果不出問題,它將會在app/build/outputs/apk 資料夾下生成打包好的檔案 類似 app-wandoujia-realease.apk 這種apk檔案。

當然如果我們希望在 apk檔案命中加入 版本資訊,和時間資訊的話,我們可以更改這個apk的檔名,我們只需在 android{} 中加入:

android.applicationVariants.all { variant ->
        def file = variant.outputs
[0].outputFile variant.outputs[0].outputFile = new File(file.parent, file.name.replace(".apk", "-" + defaultConfig.versionName +"-"+releaseTime()+ ".apk")) }

其中releaseTime()是自己定義的一個函式:

def releaseTime(){
    return new Date().format("yyyy-MM-dd")
}

這樣我們繼續執行打包命令,就會在build/outputs/apk/得到 如 app-wandoujia-debug-1.0.0-2016-08-02.apk這樣的檔案。
如果不使用命令列,也可以使用android studio 右邊的快捷方式
這裡寫圖片描述
根據需要單機即可,如果想只打包release版,就點選 assembleRelease

最終會根據不同的渠道生成渠道包:
這裡寫圖片描述

這樣就完成了自動化打包。

接下來我們說話一下 簽名的配置,以及一些打包的選項。
我們配置簽名的話,可以在android{ signingConfigs{} } 中進行配置,例如:

android {
    signingConfigs {
        release {
            keyAlias 'xxxx'
            keyPassword 'xxxx'
            storeFile file('/xxxx.jks')
            storePassword 'xxx'
        }
        debug {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('/debug.keystore')
            storePassword 'android'
        }
    }

然後在android{ buildTypes{}} 中寫:

 release {
            minifyEnabled false
            buildConfigField("boolean", "LOG_DEBUG", "false")
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig = signingConfigs.release
        }
        debug {
            buildConfigField("boolean", "LOG_DEBUG", "true")
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig = signingConfigs.debug
        }

他們分別用來打包release版和debug版
其中有一些選項可以設定:
minifyEnabled 這個選項決定是否混淆
proguardFiles 這個指定了混淆的配置檔案路徑,預設是app目錄下的 proguard-rules.pro
shrinkResources 可以移除無用資源
….

buildConfigField 這個屬性可以在 java程式碼包名地下的 BuildConfig中加入欄位
這句程式碼 buildConfigField(“boolean”, “LOG_DEBUG”, “true”)作用是在BuildConfig
中加入了一個域 public static final boolean LOG_DEBUG = true;
這樣我們就可以在 java程式碼中判斷,是否為debug版本了。
這裡寫圖片描述

最後我附上我的配置:

apply plugin: 'com.android.application'
apply plugin: 'android-apt'
android {
    signingConfigs {
        release {
            keyAlias 'xxx'
            keyPassword 'xxxxxx'
            storeFile file('/xxx.jks')
            storePassword 'xxxxx'
        }
        debug {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('/debug.keystore')
            storePassword 'android'
        }
    }
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
        applicationId "xxxxxx"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            buildConfigField("boolean", "LOG_DEBUG", "false")
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig = signingConfigs.release
        }
        debug {
            buildConfigField("boolean", "LOG_DEBUG", "true")
            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig = signingConfigs.debug
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
            java.srcDirs = ['src/main/java', 'src/main/java-gen']
        }
    }
    productFlavors {
        wandoujia {
        }
        qihu360 {
        }
        baidu {
        }
        productFlavors.all {
            flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
        }
    }
    android.applicationVariants.all { variant ->
        def file = variant.outputs[0].outputFile
        variant.outputs[0].outputFile = new File(file.parent,
                file.name.replace(".apk", "-" + defaultConfig.versionName +"-"+releaseTime()+ ".apk"))

    }
}
def releaseTime(){
    return new Date().format("yyyy-MM-dd")
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    }