如果你還在手動的對每個市場進行打包,先不說 Low 不 Low,自己也會覺得很痛苦對吧,甚至有的同學使用 Windows build 打包一次就得 3-5min;打 6 個市場包半個小時就過去了,最重要的是這個過程中還有可能出現錯誤,增加測試的難度與成本。

多渠道打包也有很多種方式;有遠端的 jenkins + gradle +github 等方法;網上資料很多,由於這種方式需要的配置環境比較繁瑣;適用於需要大量打包的企業,並且需要遠端打包的需求;本文將介紹 Android Studio 本地一鍵打包與自動配置簽名的方法;

廢話說這個多,現在開始搞定多渠道打包;

一、在 AndroidManifest.xml 裡設定動態渠道變數

<!-- 自動升級型別  self、_360、baidu -->
        <meta-data
            android:name="sdk_key_version_update_type"
            android:value="${CHANNEL_VALUE}" />

二、在 build.gradle 設定 productFlavors

這裡假定我們需要打包的渠道為 360、google、百度 以及本公司

方法 1:直接在 app:gradle 下配置

android {  

    defaultConfig {
        ...
        flavorDimensions "versionCode"
    }
    productFlavors {
        google {
            manifestPlaceholders = [CHANNEL_VALUE: "google"]
        }
        qh360 {
            manifestPlaceholders = [CHANNEL_VALUE: "360"]
        }
        baidu {
            manifestPlaceholders = [CHANNEL_VALUE: "baidu"]
        }
        self {
            manifestPlaceholders = [CHANNEL_VALUE: "self"]
        }
    }  
}

或者批量修改

defaultConfig {
        ...
        flavorDimensions "versionCode"
    }

android {  
    productFlavors {
        kuan {}
        xiaomi {}
        qh360 {}
        baidu {}
        wandoujia {}
    }  

    productFlavors.all { 
        flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name] 
    }
}

上面這個配置的作用就是,為每個渠道包產生不同的 CHANNEL_VALUE 的值。這裡需要注意的是你對應的標籤與配置的 Name 獲取邏輯一定要保持一致,否則會出現找不到的邏輯異常。

方法 2:通過快捷鍵 command + ; 開啟配置介面。( Windows 對應的快捷鍵 Ctrl + Alt + Shift + S )並新增對應的配置渠道。如下圖:

這裡寫圖片描述

注意:這裡僅修改 Name 即可,其他資訊無特別需求不要修改

三、執行打包操作

開啟 Build App 介面:

這裡寫圖片描述

輸入對應的資訊點選 Next:

這裡寫圖片描述

選中對應的渠道版本點選 Finish 即可在專案的 app: 目錄 下看到對應的apk檔案。

這裡寫圖片描述

四、執行打包命令 ./gradlew assembleRelease

除了使用 AndroidStudio 圖形打包操作以外,我們也可以使用命令列進行打包操作,具體步驟如下:

在 AndroidStudio 視窗左下角開啟 Terminal 面板,輸入 gradlew assembleRelease 命令即可。

五、配置簽名檔案

由於使用命令時打出的包是未簽名的檔案,這個和我們的一鍵打包還有些瑕疵。對此我們需要配置下簽名檔案。

首先在專案目錄下的 gradle.properies 下配置簽名檔案的 keyPassWord 與 storePassWord 。

APK_SIGN_KEY_PASSWORD=******
APK_SIGN_STORE_PASSWORD=******

這樣做得好處是沒必要把對應的密碼暴露出去

    //簽名
    signingConfigs {
        release{
            keyAlias '1'
            keyPassword APK_SIGN_KEY_PASSWORD
            storeFile file('../snaillove.keystore')
            storePassword APK_SIGN_STORE_PASSWORD
        }
        debug{
            keyAlias '1'
            keyPassword APK_SIGN_KEY_PASSWORD
            storeFile file('../snaillove.keystore')
            storePassword APK_SIGN_STORE_PASSWORD
        }

    }

    buildTypes {
        release {
            //啟用混淆程式碼的功能
            minifyEnabled false
            //指定混淆規則,需要壓縮優化的混淆要把proguard-android.txt換成proguard-android.txt
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }

注意:一定要把 signingConfigs 檔案配置到 buildTypes 前面 否則會編譯時丟擲異常 Could not find property ‘debugConfig’ on SigningConfig container.

配置自定義打包路徑與名稱

生成對應的 APK 後,如果還需要我們手動的去修改對應的名稱或者路徑,是否根標題的一鍵還有些距離?OK,接著來,這裡我們輸出 apk 名稱為 com_biniusports_app_bnsports_v1.0.0_20171205_baidu.apk 的路徑:

    android {
        // 自定義APK輸出配置
        applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                // 輸出apk名稱為com_biniusports_app_bnsports_v1.0.0_20171205_baidu.apk
                def fileName = "com_biniusports_app_bnsports_v${defaultConfig.versionName}_${getNowTime()}_${variant.productFlavors[0].name}.apk"
                outputFileName = fileName
                }
            }
        }
    }

//獲取時間戳
def getNowTime() {
    def date = new Date()
    def now = date.format('yyyyMMdd')
    return now
}

注意:Android Studio 版本大於 3.0 時不要使用v ariant.outputs.each 進行查詢內容並且不要使用 new File(outputFile.parent, fileName),否則會丟擲異常 Android Gradle 3.0.0-alpha2 plugin, Cannot set the value of read-only property ‘outputFile’。

完成以上配置後,即可開心的點選執行按鈕進行簽名打包了;

這裡寫圖片描述

如出現如圖的路徑與對應的 APK 名稱,恭喜你,本地一鍵多渠道打包已收入囊中。