標籤:

Android多渠道打包詳細解析

一、多渠道打包概述

由於國內存在著有眾多的應用市場,在不同的應用市場可能有不同的統計需求,為此Android開發人員需要為每個應用市場發布一個安裝包,這裡就引出了Android的多渠道打包。在安裝包中添加不同的標識,以此區分各個渠道,方便統計app在市場的各種效果。

因此,每當發新版本時,市場會提供一個渠道列表,Android RD會根據這些渠道相應地生成等量的渠道包。隨著渠道越來越多,為了提高渠道打包的效率,因此催生了對多渠道打包的方式的研究。

本篇文章主要總結一下多渠道打包的相關知識以及美團的新舊兩種多渠道打包方案。

二、渠道包生成

Maven方式: 每打一個包都要執行一遍構建過程,效率太低;

apktool: 雖然不需要重新構建,但對每個包都要重新簽名;

隨著渠道包的增多,每次打包動輒幾個小時,以上兩種方式的效率太低。

關於這兩種打包方式詳見:美團Android自動化之旅—生成渠道包

META-INF添加空文件

這是美團為了提高打包效率而提出的一種新的多渠道打包方式,不需要重新構建,也不需要重新簽名。

介紹

通過解壓apk,根目錄下會有一個META-INF目錄,在該目錄下添加空文件,可以不用重新簽名應用。因此,通過為不同渠道的應用添加不同的空文件,可以唯一標識一個渠道。

具體步驟

  • 利用python代碼用來給apk添加空的渠道文件
  • 在Java代碼中讀取空渠道文件名,識別渠道

具體代碼在上面美團生成多渠道包的鏈接中有詳細給出。

Walle

Walle(瓦力):Android Signature V2 Scheme簽名下的新一代渠道包打包神器

瓦力通過在Apk中的APK Signature Block區塊添加自定義的渠道信息來生成渠道包,從而提高了渠道包生成效率,可以作為單機工具來使用,也可以部署在HTTP伺服器上來實時處理渠道包Apk的升級網路請求。

原理介紹

Android 7.0(Nougat)引入一項新的應用簽名方案APK Signature Scheme v2,它是一個對全文件進行簽名的方案,能提供更快的應用安裝時間、對未授權APK文件的更改提供更多保護,在默認情況下,Android Gradle 2.2.0插件會使用APK Signature Scheme v2和傳統簽名方案來簽署你的應用。

新應用簽名方案的簽名信息會被保存在區塊(APK Signing Block)中, 而區塊(Contents of ZIP entries)、區塊(ZIP Central Directory)、區塊(ZIP End of Central Directory)是受保護的,在簽名後任何對其的修改都逃不過新的應用簽名方案的檢查。

之前的渠道包生成方案是通過在META-INF目錄下添加空文件的打包方式在Signature Scheme v2的簽名方式下不可使用了,因為META-INF已經被列入了保護區了,向META-INF添加空文件的方案會對上面受保護的三個區塊都有影響。

通過上面描述發現區塊(APK Signing Block)是不受簽名校驗規則保護的,因此Walle正是通過在該區塊做文章,寫入渠道信息。

具體步驟

  • 對新的應用簽名方案生成的APK包中區塊(APK Signing Block)寫入渠道信息,並保存在APK中
  • APK在安裝過程中進行的簽名校驗,是忽略我們添加的渠道信息的,這樣就能正常安裝了
  • 在App運行階段,可以通過ZIP的End of central directoryCentral directory等結構中的信息找到我們自己添加的渠道信息,從而實現獲取渠道信息的功能

最終,每打一個渠道包只需複製一個APK,然後在APK中添加一個渠道信息即可,這種打包方式速度非常快。

使用方式

  • Gradle插件方式,方便快速集成
  • 命令行方式,最大化滿足各種自定義需求

關於Walle兩種使用方式的詳細步驟,參見:Android使用walle多渠道打包

三、渠道包適配

上述多渠道打包方式解決了打包慢的問題,但是隨著渠道越來越多,不同渠道對應用的要求也不盡相同。

例如,有的渠道要求app的應用名不同,有些渠道要求應用不能使用第三方統計工具,有些渠道要求應用不能自動更新。

之前的做法是為每個需要適配的渠道創建一個Git分支,發版時再切換到相應的分支,併合並主分支的代碼。適配的渠道比較少的話這種方式還可以接受,隨著適配渠道的增多,這種方式就變得不可取。

幸好Gradle flavor,可以滿足渠道適配的需求,只需要通過配置Gradle即可以實現多渠道的適配工作,省心省力。

Flavor

先來看build.gradle文件中的一段代碼:

android {
....

productFlavors {
flavor1 {
minSdkVersion 14
}
}
}

上例定義了一個flavorflavor1,並指定了應用的minSdkVersion為14(當然還可以配置更多的屬性,具體可參考相關文檔)。與此同時,Gradle還會為該flavor關聯對應的sourceSet,默認位置為src/<flavorName>目錄,對應到本例就是src/flavor1

接下來,要做的就是根據具體的需求在build.gradle文件中配置flavor,並添加必要的代碼和資源文件。以flavor1為例,運行gradle assembleFlavor1命令既可生成所需的適配包。通過適配不同的flavor即可以生成不同的渠道包,但該方式生成渠道包的方式需要重複編譯構建。

具體示例

使用不同的包名

productFlavors {
qq {
applicationId "com.hello.group.qq"
}
}

面的代碼添加了一個名為qq的flavor,並指定了應用的包名為com.hello.group.qq,運行gradle assembleqq命令即可生成qq適配包。

使用不同的應用名

Gradle在構建應用時,會優先使用flavor所屬sourceSet中的同名資源。所以,解決思路就是在flavorsourceSet中添加同名的字元串資源,以覆蓋默認的資源。

首先,在build.gradle配置文件中添加如下flavor:

android {
productFlavors {
wandoujia {
}
}
}

上面的配置會默認src/wandoujia目錄為wandoujia flavor的sourceSet

接下來,在src目錄內創建wandoujia目錄,並添加如下應用名字元串資源(src/wandoujia/res/values/appname.xml):

<resources>
<string name="app_name">wandoujia_app</string>
</resources>

默認的應用名字元串資源如下(src/main/res/values/strings.xml):

<resources>
<string name="app_name">origin_app</string>
</resources>

最後,運行gradle assembleWandoujia命令即可生成應用名為wandoujia_app的應用了。

wandoujia包下不使用strings.xml 名是因為會出現文件重複,默認的main 文件夾里存在的文件在其他適配目錄中不允許出現相同文件名的文件。

更多flavor適配示例,參見:美團Android自動化之旅—適配渠道包

以上就是最近了解關於多渠道打包的相關知識的總結。

想要實現更多自定義適配多渠道包的需求,還要更多的了解Gradle相關知識。

自己是從事了七年開發的Android工程師,不少人私下問我,2019年Android進階該怎麼學,方法有沒有?

沒錯,年初我花了一個多月的時間整理出來的學習資料,希望能幫助那些想進階提升Android開發,卻又不知道怎麼進階學習的朋友。【包括高級UI、性能優化、架構師課程、NDK、Kotlin、混合式開發(ReactNative+Weex)、Flutter等架構技術資料】,希望能幫助到您面試前的複習且找到一個好的工作,也節省大家在網上搜索資料的時間來學習。

喜歡我的文章可以點贊+關注我的【個人主頁】獲取免費資料,後續我將繼續分享更多Android技術乾貨,感謝支持!

資料大全

推薦閱讀:

TAG:Android開發 |