1. 程式人生 > >Android多渠道打包技術對比

Android多渠道打包技術對比

前言

本文整理自我去年在公司內部做的一次分享,去掉了公司的資訊,整理出來分享一下。
希望對讀者有所幫助。

加入公司後,就一直負責App的多渠道打包,今天來分享一下多渠道打包技術的介紹與對比,以及我們最後的選擇。

什麼是多渠道打包技術

我們知道,由於某種黑暗力量,Android的親爹市場 GooglePlay 不能進入大陸,導致大陸 Android 市場眾多,如:小米、豌豆莢、華為等等等。

當新版本釋出,我們需要通過渠道號來區分不同的市場,為不同市場生成不同的包,再把對應的包上傳到各個市場。這種為App打出不同渠道包的技術稱為多渠道打包技術

怎麼去做多渠道打包

多渠道打包實現有多種,但是有兩點不會變:

  1. 渠道區分
  2. 打包

接下去介紹一下現今的多渠道打包技術,以及它們之間的對比。

Umeng+Gradle

我們 App 集成了 Umeng 的服務,所以就拿它舉例了,事實上,不用 Umeng 也沒有絲毫關係。

渠道的區分

AndroidManifest.xml中配置一個meta-data

123 <meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL_NAME}"/>

然後在app/build.gradle裡配置productFlavors

12345678 productFlavors
{ def path = "channels.txt" file(path).eachLine { channel -> "$channel" { manifestPlaceholders = [CHANNEL_NAME: channel] } }}
PS:channels.txt 是渠道列表檔案,每一行代表一個渠道,這樣方便管理。

打包方法

使用 ./gradlew assembleRelease命令,就可以打出多渠道的包了。

原理

該種方式的打包原理是利用了 Gradle 的flavors功能來實現的,渠道的獲取是通過如下程式碼方式獲取。

12 ApplicationInfo appInfo = cxt.getPackageManager().getApplicationInfo(cxt.getPackageName(), PackageManager.GET_META_DATA);String channel = String.valueOf(appInfo.metaData.get("UMENG_CHANNEL"));

優缺點

優點:

  1. 簡單,易懂,沒什麼門檻,也不需要依賴其他工具與外掛。
  2. Gradle強大的flavor功能,可以實現不同渠道擁有不同的程式碼實現,可以給渠道做定製包。
  3. 擴充套件性強大,沒有相容性問題。

缺點:

  1. 打包速度極慢,因為每個渠道包都是從“0到1”,渠道一多,打包時間以小時為單位。

PS:我們 App 幾百個渠道,用這種方式打包需要2多個小時,怎麼受得了?。

所以,該方式適合渠道不多的時候使用,或者不同渠道需要使用不同的程式碼。

上面說到,每個渠道包都是從“0到1”,然而實際上,渠道包之間的唯一差別僅僅在於一個渠道號(這裡暫時只考慮不同渠道的程式碼相同),如果能拿已經打好的包,拿來修改一下渠道號,變成另一個渠道包,那這速度就能大幅度提高了。

美團的打包方案,利用META-INF(解壓APK可以看到)不參與 APK 簽名的原理,在META-INF新增空的檔案來代表渠道,實現了這個功能,極大的提高了打包的速度。

渠道的區分

META-INF目錄下新增空檔案,再在程式碼中讀取檔名獲取()。

PS:可以去市場下載一個美團 APP 來解壓一下看看。

打包方法

由於美團並沒有給出具體的實現程式碼,所以我當時嘗試的是開源實現:安卓多渠道打包工具

原理

上面已經提到了,META-INF不參與 APK 簽名。

META-INF目錄下新增一個空的檔案來代表渠道名。

這樣就可以只打一次簽名包,後續只需拷貝,新增渠道檔案即可。

優缺點

優點:

  1. 速度極快,每打一個包就只需要複製一個APK,並新增一個空檔案即可。(900個包一分鐘,我天)
  2. 可以利用已存在的包打新的渠道包。(可多個)

第2點其實也是非常棒的優點,當需要一個新的渠道包時,不再需要停下工作,去儲存程式碼,切分支,build,打包,只要一個已存在的包,一個命令就好,非常方便。

缺點:

  1. 不安全,由於不需要簽名,所以任何人都可以拿到已有的包,修改成任意其他渠道的包,可能會被惡意利用汙染渠道資料。
  2. 擴充套件性較差。(暫時沒有Gradle的實現方案,相對來說選擇餘地較小,擴充套件性也差一些)
  3. 不支援 flavors
  4. 潛在風險,現在META-INF不參與APK簽名,萬一以後參與了,那麼這套方案就失效了,當然這個概率估計很小。
  5. 似乎不支援 android 7.0?issue(沒親測,未知)
  6. 需要修改程式碼,修改渠道的獲取方式(Umeng配置修改)

美團打包方式是一次大創新,最吸引人的就是速度快,真心快,就是打包的時間喝杯水再也不夠了。

名字太長,簡稱為 packer 吧。號稱『下一代Android打包工具』,擁有與美團的方案相媲美的打包速度。

原理

我們知道,其實 APK 是一個 Zip 檔案,所以 APK 擁有 Zip 格式的特點。

該方法利用 Zip 格式的特點,修改Comment LengthFile Comment兩個欄位,不會對ZIP檔案造成破壞,將渠道資訊放入其中,達到修改渠道的目的。由於修改以上內容也不需要重新簽名打包,所以擁有與美團的方案相媲美的打包速度。

更多詳情,見原專案Github。

渠道區分

渠道資訊存放在APK檔案的註釋欄位File Comment,在程式碼中使用 packer 提供的方法獲取。

打包方法

提供了三種實現方式,Gradle、Java、Python,都可以使用。

優缺點

優點:

  1. 打包速度極快。(與美團方案速度差不多)
  2. 選擇性更多,作者很良心,提供了Gradle,Java,Python三種實現。
  3. 擴充套件性強大,由於有 Gradle 的實現方案,所以擴充套件性有了保障。

缺點:

  1. 不支援 flavors
  2. 需要修改程式碼,修改渠道的獲取方式。(Umeng配置修改)
  3. 潛在風險,Zip 格式萬一修改,那麼該方式失效,這概論應該也非常低。
  4. 已知360加固後,重新簽名Apk後會抹去渠道資訊。

小結

packer 利用 Zip 格式,又一個多渠道打包的創新,速度極快,又安全,非常棒!

對比

對比項 Gradle 美團 packer
是否支援 flavors
打包速度 極快 極快
安全性 有風險
擴充套件性 較低 較高
相容性問題
風險 極低 極低
加固影響 未測試 丟失渠道資訊(360加固)

如何選擇?

目前只有Gradle支援flavors功能,所以如果這個需求強烈,那麼就只能選擇Gradle。

如果沒有這個需求,那麼相對於美團打包的方式,第三種方式packer更加安全一些,速度方面也令人滿意。

當然如果使用美團方式,可以在服務端過濾非法的渠道,也是可以的!~(看了美團的 APK,渠道是明文的,所以估計也是在服務端處理的,如果用的是 Umeng 統計,那麼就不行嘍)。

最後我們的選擇是,以packer為主,Gradle為輔。

資料