前言
其實本文大部分資料都來自github和google,如何有興趣的讀者躬存,可以直接閱讀官方文檔~
什么是Gradle
Android 構(gòu)建系統(tǒng)編譯應(yīng)用資源和源代碼张惹,然后將它們打包成可供您測試、部署岭洲、簽署和分發(fā)的 APK宛逗。 Android Studio 使用?Gradle?這一高級構(gòu)建工具包來自動執(zhí)行和管理構(gòu)建流程,同時也允許您定義靈活的自定義構(gòu)建配置盾剩。
每個構(gòu)建配置均可自行定義一組代碼和資源雷激,同時對所有應(yīng)用版本共有的部分加以重復(fù)利用替蔬。 Android Plugin for Gradle 與這個構(gòu)建工具包協(xié)作,共同提供專用于構(gòu)建和測試 Android 應(yīng)用的流程和可配置設(shè)置屎暇。
Gradle 和 Android 插件獨立于 Android Studio 運行承桥。 這意味著,您可以在 Android Studio 內(nèi)根悼、計算機上的命令行或未安裝 Android Studio 的計算機(例如持續(xù)性集成服務(wù)器)上構(gòu)建 Android 應(yīng)用凶异。
如果您不使用 Android Studio,可以學(xué)習(xí)如何從命令行構(gòu)建和運行您的應(yīng)用挤巡。 無論您是從命令行剩彬、在遠(yuǎn)程計算機上還是使用 Android Studio 構(gòu)建項目,構(gòu)建的輸出都相同矿卑。
注:由于 Gradle 和 Android 插件獨立于 Android Studio 運行喉恋,您需要單獨更新構(gòu)建工具。
請閱讀版本說明粪摘,了解如何更新 Gradle 和 Android 插件。Android 構(gòu)建系統(tǒng)非常靈活绍坝,讓您能夠在不修改應(yīng)用核心源文件的情況下執(zhí)行自定義構(gòu)建配置徘意。
什么是VasDolly?(github 傳送門)
VasDolly是騰訊開源的一個高效的打包工具。騰訊作為國內(nèi)的技術(shù)大廠轩褐,在技術(shù)層面上還是很牛逼and可靠的椎咧。而且開發(fā)團隊在github上也是相對的活躍,對issue也解決也是很積極的把介。
VasDolly是一種快速多渠道打包工具勤讽,同時支持基于V1簽名和V2簽名進行多渠道打包。插件本身會自動檢測Apk使用的簽名類別拗踢,并選擇合適的多渠道打包方式脚牍,對使用者來說完全透明。
VasDolly 是騰訊推出的新一代打包工具巢墅,相對于傳統(tǒng)的打包工具诸狭,即AS自帶的打包工具,速度有了非一般的提升君纫。
Gradle Plugin本身提供了多渠道的打包策略: 首先驯遇,在AndroidManifest.xml中添加渠道信息占位符:
<meta-data android:name="InstallChannel" android:value="${InstallChannel}" />
然后,通過Gradle Plugin提供的productFlavors標(biāo)簽蓄髓,添加渠道信息:
productFlavors{
"YingYongBao"{ manifestPlaceholders = [InstallChannel : "YingYongBao"] }
"360"{ manifestPlaceholders = [InstallChannel : "360"] }
}
這樣叉庐,Gradle編譯生成多渠道包時,會用不同的渠道信息替換AndroidManifest.xml中的占位符会喝。我們在代碼中陡叠,也就可以直接讀取AndroidManifest.xml中的渠道信息了玩郊。
但是,這種方式存在一些缺點:
每生成一個渠道包匾竿,都要重新執(zhí)行一遍構(gòu)建流程瓦宜,效率太低,只適用于渠道較少的場景岭妖。
Gradle會為每個渠道包生成一個不同的BuildConfig.java類临庇,記錄渠道信息,導(dǎo)致每個渠道包的DEX的CRC值都不同昵慌。一般情況下假夺,這是沒有影響的。但是如果你使用了微信的Tinker熱補丁方案斋攀,那么就需要為不同的渠道包打不同的補丁已卷,這完全是不可以接受的。(因為Tinker是通過對比基礎(chǔ)包APK和新包APK生成差分補丁淳蔼,然后再把補丁和基礎(chǔ)包APK一起合成新包APK侧蘸。這就要求用于生成差分補丁的基礎(chǔ)包DEX和用于合成新包的基礎(chǔ)包DEX是完全一致的,即:每一個基礎(chǔ)渠道包的DEX文件是完全一致的鹉梨,不然就會合成失敾浒)
那有沒有一種方案:可以在添加渠道信息后,不需要重新簽名存皂?
答案就是:VasDolly 晌坤。
背景
Android在國內(nèi)的市場極度的碎片化,各大應(yīng)用市場樂此不疲旦袋,OEM廠商也都自立山頭骤菠。而作為一個成熟的、商業(yè)化的App疤孕,必然是要在各個應(yīng)用市場占坑霸榜的商乎。所以運營的同事一般都會要求Android小哥哥提供幾個甚至十幾個不同渠道的渠道包。而傳統(tǒng)的打包工具的打包速度大家都心知肚明的祭阀,盡管Google不斷的優(yōu)化截亦,但還是差強人意。因此一個快速柬讨,高效的打包工具就很必要了崩瓤,可以節(jié)省開發(fā)小哥哥大量的工作時間。
使用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 為了方便經(jīng)常git版本管理,我放在了項目的根目錄下
channelFile.txt 中的內(nèi)容是每一個渠道都單獨成行
直接編譯生成多渠道包
若是直接編譯生成多渠道包趁啸,首先要配置渠道文件强缘、渠道包的輸出目錄和渠道包的命名規(guī)則:
channel{
//指定渠道文件
channelFile=file("../channelFile.txt")
//多渠道包的輸出目錄,默認(rèn)為new File(project.buildDir,"channel")
baseOutputDir = new File("${project.buildDir}/channelRoot/test")
//多渠道包的命名規(guī)則不傅,默認(rèn)為${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}
apkNameFormat='${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}'
//快速模式:生成渠道包時不進行校驗(速度可以提升10倍以上旅掂,默認(rèn)為false)
isFastMode=true
//buildTime的時間格式,默認(rèn)格式:yyyyMMdd-HHmmss
buildTimeDateFormat='yyyyMMdd-HH:mm:ss'
//低內(nèi)存模式(僅針對V2簽名访娶,默認(rèn)為false):只把簽名塊商虐、中央目錄和EOCD讀取到內(nèi)存,不把最大頭的內(nèi)容塊讀取到內(nèi)存崖疤,在手機上合成APK時秘车,可以使用該模式
lowMemory=false
}
其中,多渠道包的命名規(guī)則中劫哼,可使用以下字段:
appName : 當(dāng)前project的name
versionName : 當(dāng)前Variant的versionName
versionCode : 當(dāng)前Variant的versionCode
buildType : 當(dāng)前Variant的buildType叮趴,即debug or release
flavorName : 當(dāng)前的渠道名稱
appId : 當(dāng)前Variant的applicationId
buildTime : 當(dāng)前編譯構(gòu)建日期時間,時間格式可以自定義沦偎,默認(rèn)格式:yyyyMMdd-HHmmss
然后疫向,通過gradle channelDebug咳蔚、gradle channelRelease命令分別生成Debug和Release的多渠道包豪嚎。
為了方便臨時生成渠道包進行測試,我們從v2.0.0開始支持添加渠道參數(shù):gradle channelDebug(channelRelease) -Pchannels=yingyongbao,gamecenter谈火,這里通過屬性channels指定的渠道列表擁有更高的優(yōu)先級侈询,且和原始的文件方式是互斥的。
選擇使用V1 還是V2簽名
目前Gradle Plugin 2.2以上默認(rèn)開啟V2簽名糯耍,所以如果想關(guān)閉V2簽名扔字,可將下面的v2SigningEnabled設(shè)置為false。
signingConfigs {?
? ? ? release {
? ? ?? ? ?...? ? ? ? ? ?
? ? ?? ? ?v1SigningEnabledtruev2SigningEnabledfalse
? ? ?}? ? ? ?
debug {
? ? ?...? ? ? ? ? ?
? ? ?v1SigningEnabledtruev2SigningEnabledfalse
? ? ?}?
}
如圖
讀取渠道信息
通過helper類庫中的ChannelReaderUtil類讀取渠道信息温技。
Stringchannel=ChannelReaderUtil.getChannel(getApplicationContext());
如果沒有渠道信息革为,那么這里返回null,開發(fā)者需要自己判斷舵鳞。
調(diào)用Gradle Task 一鍵生成多個release版本渠道包震檩,或者debug渠道包
在集成成功之后,重新rebuild項目,VasDolly就會自動在項目的Gradle Task中生成對應(yīng)的Task 抛虏,在需要發(fā)布正式版的時候只要選擇對應(yīng)的task即可
完成打包之后博其,就可以在直接配置的輸出目錄中看到生成的應(yīng)用安裝包了
使用命令行生成渠道包
為了方便臨時生成渠道包進行測試,VasDolly從v2.0.0開始支持添加渠道參數(shù):gradle channelDebug(channelRelease) -Pchannels=yingyongbao,gamecenter迂猴,這里通過屬性channels指定的渠道列表擁有更高的優(yōu)先級慕淡,且和原始的文件方式是互斥的。
效果等同于上一種使用方式
Demo參考
詳細(xì)的接入范式沸毁,可參考Demo
或者參考我自己寫的Demo