一、多渠道打包概述
由於國記憶體在著有眾多的應用市場,在不同的應用市場可能有不同的統計需求,為此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 directory
、Central directory
等結構中的資訊找到我們自己新增的渠道資訊,從而實現獲取渠道資訊的功能
最終,每打一個渠道包只需複製一個APK,然後在APK中新增一個渠道資訊即可,這種打包方式速度非常快。
使用方式
-
Gradle外掛方式,方便快速整合
-
命令列方式,最大化滿足各種自定義需求
關於Walle兩種使用方式的詳細步驟,參見:Android使用walle多渠道打包
三、渠道包適配
上述多渠道打包方式解決了打包慢的問題,但是隨著渠道越來越多,不同渠道對應用的要求也不盡相同。
例如,有的渠道要求app的應用名不同,有些渠道要求應用不能使用第三方統計工具,有些渠道要求應用不能自動更新。
之前的做法是為每個需要適配的渠道建立一個Git分支,發版時再切換到相應的分支,併合並主分支的程式碼。適配的渠道比較少的話這種方式還可以接受,隨著適配渠道的增多,這種方式就變得不可取。
幸好Gradle flavor,可以滿足渠道適配的需求,只需要通過配置Gradle即可以實現多渠道的適配工作,省心省力。
Flavor
先來看build.gradle
檔案中的一段程式碼:
android {
....
productFlavors {
flavor1 {
minSdkVersion 14
}
}
}
複製程式碼
上例定義了一個flavor
:flavor1
,並指定了應用的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
中的同名資源。所以,解決思路就是在flavor
的sourceSet
中新增同名的字串資源,以覆蓋預設的資源。
首先,在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相關知識。