Android 多渠道打包配置

看完這篇你學到什麼:php

  • 熟悉gradle的構建配置
  • 熟悉代碼構建環境的目錄結構,你知道的不只僅是隻有src/main
  • 開發、生成環境等等環境能夠任意切換打包
  • 多渠道打包
  • APK輸出文件配置

需求

通常咱們開發的環境分爲:debug 和 release,可是你想再份內測1環境、內測2環境等等怎麼辦呢?html

這就須要依賴強大的gradle 來配置了。java

相關的配置也能夠參考谷歌官方文檔android

配置構建類型 buildTypes

*名詞解析:*咱們一般會分不一樣的編譯環境進行打包,好比有debug、release、beta等環境參數,像這種咱們就稱之爲buildTypes.git

您能夠在模塊級 build.gradle 文件的 android {} 代碼塊內部建立和配置構建類型。當您建立新模塊時,Android Studio 會自動爲您建立調試和發佈這兩種構建類型。儘管調試構建類型不會出如今構建配置文件中,Android Studio 會將其配置爲 debuggable true。這樣,您能夠在安全的 Android 設備上調試應用並使用通用調試密鑰庫配置 APK 簽署。github

若是您但願添加或更改特定設置,您能夠將調試構建類型添加到您的配置中。如下示例爲調試構建類型指定了 applicationIdSuffix,並配置了一個使用調試構建類型中的設置進行初始化的jnidebug構建類型。api

applicationIdSuffix: 字段表示,在不改變你默認的程序ID(包名)的狀況下,爲其添加後綴。好比你的包名是com.rae.app,但你想區分測試包和正式包的狀況,這個時候將applicationIdSuffix設置爲.debug,那麼你的應用程序對應的包名就變成了com.rae.app.debug安全

android {
    ...
    defaultConfig {...}
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            applicationIdSuffix ".debug"
        }

        /** * The 'initWith' property allows you to copy configurations from other build types, * so you don't have to configure one from the beginning. You can then configure * just the settings you want to change. The following line initializes * 'jnidebug' using the debug build type, and changes only the * applicationIdSuffix and versionNameSuffix settings. */

        jnidebug {

            // This copies the debuggable attribute and debug signing configurations.
            initWith debug

            applicationIdSuffix ".jnidebug"
            jniDebuggable true
        }
    }
}
複製代碼

構建源集

名詞解析: 一般源代碼是放在src/main 文件夾下的,但你想能夠根據不一樣的構建類型(好比debug、release)區分不一樣的源文件,這樣對應創建的文件夾就是一個不一樣的構建源。打個比方,debug的構建源爲src/debug,release的構建源爲src/release,而在src/main定義的爲公共資源,最後在構建的時候會進行合併操做。app

更多參考官網文檔ide

Android Studio 按邏輯關係將每一個模塊的源代碼和資源分組爲源集。模塊的 main/ 源集包括其全部構建變體共用的代碼和資源。其餘源集目錄爲可選項,在您配置新的構建變體時,Android Studio 不會自動爲您建立這些目錄。不過,建立相似於 main/ 的源集有助於讓 Gradle 只應在構建特定應用版本時使用的文件和資源井井有理:

構建源的命名規則以下:

productFlavor 表示渠道包,能夠看下面的多渠道打包

  • src/main/ 此源集包括全部構建變體共用的代碼和資源。

  • src/<buildType>/ 建立此源集可加入特定構建類型專用的代碼和資源。示例:src/jnidebug

  • src/<productFlavor>/ 建立此源集可加入特定產品風味專用的代碼和資源。好比百度渠道包:src/baidu

  • src/<productFlavorBuildType>/ 建立此源集可加入特定構建變體專用的代碼和資源。

例如,要生成應用的「徹底調試」版本,構建系統須要合併來自如下源集的代碼、設置和資源。好比:百度的開發環境包:src/baiduDebug

構建類型的依賴配置

不少時候咱們會把sdk或者api接口單獨作成一個庫,通常會有生產環境和測試環境之分,但在依賴的時候每每咱們會像這樣去引用:compile project(':sdk'),這樣依賴的環境就是release,在開發調試的時候測試環境的時候就不行了。咱們得換另一種方式:

<buildType>Compile project()

這樣會根據不一樣的構建類型去依賴不一樣的包,好比咱們測試環境的依賴包:debugCompile project(':sdk'),再好比上面的jnidebugjnidebugCompile project(':sdk')

那麼問題來了,我當前的構建類型怎麼對應到其餘的module去呢?好比你的app要依賴sdk module 的debug 環境,那麼你能夠這麼作:

configuration:目標module<buildType>,好比你sdk 中<buildType>debug構建類型

debugCompile project(path: ':sdk', configuration: 'debug')

綜合示例

一、先看app這邊的build.gradle配置:

apply plugin: 'com.android.application'

android {
    buildTypes {
        release {
            minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug {
            applicationIdSuffix '.debug'
            minifyEnabled false
        }
        
        // 自定義的構建類型,名字隨便取,必定要有意義
        raedebug {
            initWith debug
            applicationIdSuffix '.raedebug'
        }
    }
}

dependencies {
    // 生成環境依賴
    releaseCompile project(path: ':sdk', configuration: 'release') // 測試環境依賴 debugCompile project(path: ':sdk', configuration: 'debug') // 自定義構建類型依賴 raedebugCompile project(path: ':sdk', configuration: 'uutest') } 複製代碼

二、sdk module的build.gradle配置:

apply plugin: 'com.android.library'

android {
       buildTypes {
        debug {
            debuggable true
            minifyEnabled false
        }
        release {
            minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } // 注意這裏,跟第一點的 raedebugCompile project的configuration要匹配。 uutest {
            initWith debug
        }
    }
}

複製代碼

多渠道打包 productFlavors

先看看build.gradle配置你就懂了

android{

    // 渠道包定義,默認定義的名稱就是渠道名稱
    productFlavors {
 
        dev {} // 測試
        baidu {}        // 百度手機助手
        yinyongbao {}   // 應用寶
        m360 {}         // 360手機助手
        pp {}           // PP助手
        anzhi{}         // 安智市場
        xiaomi {}       // 小米商店
        letv {}         // 樂視商店
        huawei {}       // 華爲商店
        lenovomm {}     // 聯想樂商店
        other {}        // 其餘市場
        official{}      // 官方版本
 
    }
 
    // 批量渠道包值替換
    productFlavors.all { flavor ->
        // 友盟、極光推送渠道包, UMENG_CHANNEL 是根據你AndroidManifest.xml來配置的,請看下面。
        flavor.manifestPlaceholders = [UMENG_CHANNEL: name, JPUSH_CHANNEL: name]
    }
}
複製代碼

AndroidManifest.xml 配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rae.demo">

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
       
       <!--變量採用${變量名}這樣來替換,不只限與<meta-data /> 標籤,任何你想替換的都行。-->
         <meta-data android:name="UMENG_APPKEY" android:value="${UMENG_APPKEY}"/>
        
        <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL}"/>
        
        <!--${變量隨變換}-->   
        <activity android:name=".DemoActivity" android:label="${變量隨變換}"/>
            
    </application>

</manifest>
複製代碼

sync gradle以後看看gradle projects 面板列表就多出了好到渠道的任務了,Build Variants 面板也相對應多了這些構建類型。

APK輸出配置

在結合到多渠道打包後,運營的那邊但願咱們給的渠道包是這種格式的app-{版本號}-{渠道名稱}.apk,那咱們來看看怎麼來知足這個多渠道打包輸出apk文件名修改的。

android{

    // 輸出文件配置
   applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) {
                def dirName = outputFile.parent // 輸出文件夾所在的位置
            
                // 文件名修改
                def fileName = "app-${output.processResources.variantName}-${defaultConfig.versionName}-${variant.flavorName}.apk"
                
                // 好比不想這麼麻煩,直接在後面加上版本號也行:
                // def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
                
                
                output.outputFile = new File(dirName, fileName)
            }
        }
    }
}
複製代碼

上面介紹的多渠道打包是採用gralde默認的配置,但有個弊端是每一個渠道包都會從新編譯一次,編譯速度慢。對大量的多渠道打包推薦用美團的walle,項目地址:github.com/Meituan-Dia…

相關文章
相關標籤/搜索