Android 渠道包生成

目前看到了兩家打包實現:
美團
騰訊VasDolly

前言

其實本文大部分資料都來自github和google,如何有興趣的讀者,可以直接閱讀官方文檔~
什麼是Gradle

Android 構建系統編譯應用資源和源代碼,然後將它們打包成可供您測試、部署、簽署和分發的 APK。 Android Studio 使用 Gradle 這一高級構建工具包來自動執行和管理構建流程,同時也允許您定義靈活的自定義構建配置。

每個構建配置均可自行定義一組代碼和資源,同時對所有應用版本共有的部分加以重複利用。 Android Plugin for Gradle 與這個構建工具包協作,共同提供專用於構建和測試 Android 應用的流程和可配置設置。

Gradle 和 Android 插件獨立於 Android Studio 運行。 這意味着,您可以在 Android Studio 內、計算機上的命令行或未安裝 Android Studio 的計算機(例如持續性集成服務器)上構建 Android 應用。

如果您不使用 Android Studio,可以學習如何從命令行構建和運行您的應用。 無論您是從命令行、在遠程計算機上還是使用 Android Studio 構建項目,構建的輸出都相同。

注:由於 Gradle 和 Android 插件獨立於 Android Studio 運行,您需要單獨更新構建工具。

請閱讀版本說明,瞭解如何更新 Gradle 和 Android 插件。Android 構建系統非常靈活,讓您能夠在不修改應用核心源文件的情況下執行自定義構建配置。

什麼是 VasDolly

VasDolly是騰訊開源的一個高效的打包工具。騰訊作爲國內的技術大廠,在技術層面上還是很牛逼and可靠的。而且開發團隊在github上也是相對的活躍,對issue也解決也是很積極的。

VasDolly是一種快速多渠道打包工具,同時支持基於V1簽名和V2簽名進行多渠道打包。插件本身會自動檢測Apk使用的簽名類別,並選擇合適的多渠道打包方式,對使用者來說完全透明。

VasDolly 是騰訊推出的新一代打包工具,相對於傳統的打包工具,即AS自帶的打包工具,速度有了非一般的提升。

Gradle Plugin本身提供了多渠道的打包策略: 首先,在AndroidManifest.xml中添加渠道信息佔位符:

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

然後,通過Gradle Plugin提供的productFlavors標籤,添加渠道信息:

productFlavors{

"YingYongBao"{ manifestPlaceholders = [InstallChannel : "YingYongBao"] }

"360"{ manifestPlaceholders = [InstallChannel : "360"] }

}

這樣,Gradle編譯生成多渠道包時,會用不同的渠道信息替換AndroidManifest.xml中的佔位符。我們在代碼中,也就可以直接讀取AndroidManifest.xml中的渠道信息了。

但是,這種方式存在一些缺點:

每生成一個渠道包,都要重新執行一遍構建流程,效率太低,只適用於渠道較少的場景。

Gradle會爲每個渠道包生成一個不同的BuildConfig.java類,記錄渠道信息,導致每個渠道包的DEX的CRC值都不同。一般情況下,這是沒有影響的。但是如果你使用了微信的Tinker熱補丁方案,那麼就需要爲不同的渠道包打不同的補丁,這完全是不可以接受的。(因爲Tinker是通過對比基礎包APK和新包APK生成差分補丁,然後再把補丁和基礎包APK一起合成新包APK。這就要求用於生成差分補丁的基礎包DEX和用於合成新包的基礎包DEX是完全一致的,即:每一個基礎渠道包的DEX文件是完全一致的,不然就會合成失敗)

那有沒有一種方案:可以在添加渠道信息後,不需要重新簽名?

答案就是:VasDolly 。

背景

Android在國內的市場極度的碎片化,各大應用市場樂此不疲,OEM廠商也都自立山頭。而作爲一個成熟的、商業化的App,必然是要在各個應用市場佔坑霸榜的。所以運營的同事一般都會要求Android小哥哥提供幾個甚至十幾個不同渠道的渠道包。而傳統的打包工具的打包速度大家都心知肚明的,儘管Google不斷的優化,但還是差強人意。因此一個快速,高效的打包工具就很必要了,可以節省開發小哥哥大量的工作時間。

使用VasDolly

在根工程的build.gradle中,添加對打包Plugin的依賴:

dependencies {     classpath'com.android.tools.build:gradle:3.0.0'classpath'com.leon.channel:plugin:2.0.3'
}

在主App工程的build.gradle中,添加對VasDolly Plugin的引用:

applyplugin:'channel'

添加對VasDolly helper類庫的依賴
在主App工程的build.gradle中,添加讀取渠道信息的helper類庫依賴:

dependencies {    api'com.leon.channel:helper:2.0.3'}

配置渠道列表
目前有兩種方式配置渠道列表,最終的渠道列表是兩者的累加之和:

在gradle.properties文件指定渠道文件名稱,該渠道文件必須位於根工程目錄下,一行一個渠道信息。

channel_file=channelFile.txt

在channel或者rebuildChannel屬性中通過channelFile屬性指定渠道文件,一行一個渠道信息。

channel{

//指定渠道文件

channelFile = file("../channelFile.txt")

}

rebuildChannel{

//指定渠道文件

channelFile = file("../channelFile.txt")

}

channelFile.txt 爲了方便經常git版本管理,我放在了項目的根目錄下
image
channelFile.txt 中的內容是每一個渠道都單獨成行
image
直接編譯生成多渠道包
若是直接編譯生成多渠道包,首先要配置渠道文件、渠道包的輸出目錄和渠道包的命名規則:

channel{

//指定渠道文件

channelFile=file("../channelFile.txt")

//多渠道包的輸出目錄,默認爲new File(project.buildDir,"channel")

baseOutputDir = new File("${project.buildDir}/channelRoot/test")

//多渠道包的命名規則,默認爲${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}

apkNameFormat='${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}'

//快速模式:生成渠道包時不進行校驗(速度可以提升10倍以上,默認爲false)

isFastMode=true

//buildTime的時間格式,默認格式:yyyyMMdd-HHmmss

buildTimeDateFormat='yyyyMMdd-HH:mm:ss'

//低內存模式(僅針對V2簽名,默認爲false):只把簽名塊、中央目錄和EOCD讀取到內存,不把最大頭的內容塊讀取到內存,在手機上合成APK時,可以使用該模式

lowMemory=false

}

其中,多渠道包的命名規則中,可使用以下字段:

appName : 當前project的name

versionName : 當前Variant的versionName

versionCode : 當前Variant的versionCode

buildType : 當前Variant的buildType,即debug or release

flavorName : 當前的渠道名稱

appId : 當前Variant的applicationId

buildTime : 當前編譯構建日期時間,時間格式可以自定義,默認格式:yyyyMMdd-HHmmss

然後,通過gradle channelDebug、gradle channelRelease命令分別生成Debug和Release的多渠道包。

爲了方便臨時生成渠道包進行測試,我們從v2.0.0開始支持添加渠道參數:gradle channelDebug(channelRelease) -Pchannels=yingyongbao,gamecenter,這裏通過屬性channels指定的渠道列表擁有更高的優先級,且和原始的文件方式是互斥的。
選擇使用V1 還是V2簽名
目前Gradle Plugin 2.2以上默認開啓V2簽名,所以如果想關閉V2簽名,可將下面的v2SigningEnabled設置爲false。


      release {

          ...           

          v1SigningEnabledtruev2SigningEnabledfalse

     }       

debug {

     ...           

     v1SigningEnabledtruev2SigningEnabledfalse

     } 

}

如圖
image

讀取渠道信息

通過helper類庫中的ChannelReaderUtil類讀取渠道信息。

Stringchannel=ChannelReaderUtil.getChannel(getApplicationContext());

如果沒有渠道信息,那麼這裏返回null,開發者需要自己判斷。

調用Gradle Task 一鍵生成多個release版本渠道包,或者debug渠道包

在集成成功之後,重新rebuild項目,VasDolly就會自動在項目的Gradle Task中生成對應的Task ,在需要發佈正式版的時候只要選擇對應的task即可
image
完成打包之後,就可以在直接配置的輸出目錄中看到生成的應用安裝包了
image

使用命令行生成渠道包

爲了方便臨時生成渠道包進行測試,VasDolly從v2.0.0開始支持添加渠道參數:gradle channelDebug(channelRelease) -Pchannels=yingyongbao,gamecenter,這裏通過屬性channels指定的渠道列表擁有更高的優先級,且和原始的文件方式是互斥的。

效果等同於上一種使用方式
image

Demo參考
詳細的接入範式,可參考Demo

或者參考我自己寫的Demo

本文轉自:https://www.jianshu.com/p/933a67a834d6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章