Andorid渠道市場有多分散呢?分散到比Android碎片化還嚴重,你還在爲多渠道打包而頭疼嗎?美團提供了速度快到白駒過隙的多渠道打包方案。說的有點誇張,對,雖然誇張,可是確實很快,不誇張不足以形容其快。廢話很少說,先講原理,再講實踐方法。html
在AndroidManifest定義渠道的年代,多渠道打包無非如下兩種方案:java
方案一:徹底的從新編譯,即在代碼從新編譯打包以前,在AndroidManifest中修改渠道標示;python
方案二:經過ApkTool進行解包,而後修改AndroidManifest中修改渠道標示,最後再經過ApkTool進行打包、簽名。android
這兩種打包方式,不論是哪一種,效率都很低,方案一毫無效率可言,並且打包的渠道規模很是小,第二種方案效率稍微高些,打包的渠道規模也還能夠,可是這兩種方案速度慢的驚人,若是你打個上百的渠道包試試,估計你的電腦能卡一下午。慢,固然也有好處,你能夠不用工做了,喝着咖啡,玩着手機慢慢等也很愜意是不?哈哈……git
美團高效的多渠道打包方案是把一個Android應用程序包看成一個zip文件包進行解壓,而後發如今簽名生成的目錄下添加一個空文件,空文件用渠道名來命名,並且不須要從新簽名。這種方式不須要從新簽名,編譯等步驟,使得這種方法很是高效。程序員
咱們直接解壓apk,解壓後的根目錄會有一個META-INF目錄,以下圖所示:github
若是在META-INF目錄內添加空文件,能夠不用從新簽名應用。所以,經過爲不一樣渠道的應用添加不一樣的空文件,能夠惟一標識一個渠道。微信
咱們用python代碼來給apk添加空的渠道文件,渠道名的前綴爲mtchannel_:app
import zipfile zipped = zipfile.ZipFile(your_apk, 'a', zipfile.ZIP_DEFLATED) empty_channel_file = "META-INF/mtchannel_{channel}".format(channel=your_channel) zipped.write(your_empty_file, empty_channel_file)
添加完空渠道文件後的目錄,META-INFO目錄多了一個名爲mtchannel_meituan的空文件:工具
咱們用腳本生成了文件以後,文件的名字是用渠道名來命名的,因此咱們在啓動程序的時候,能夠用java代碼動態讀取渠道名,並動態的去設置。
java代碼讀取渠道名的方法:
public static String getChannel(Context context) { ApplicationInfo appinfo = context.getApplicationInfo(); String sourceDir = appinfo.sourceDir; String ret = ""; ZipFile zipfile = null; try { zipfile = new ZipFile(sourceDir); Enumeration<?> entries = zipfile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = ((ZipEntry) entries.nextElement()); String entryName = entry.getName(); if (entryName.startsWith("mtchannel")) { ret = entryName; break; } } } catch (IOException e) { e.printStackTrace(); } finally { if (zipfile != null) { try { zipfile.close(); } catch (IOException e) { e.printStackTrace(); } } } String[] split = ret.split("_"); if (split != null && split.length >= 2) { return ret.substring(split[0].length() + 1); } else { return ""; } }
讀取到了渠道名,咱們就能夠動態的設置了,好比友盟渠道的動態設置方法是:AnalyticsConfig.setChannel(getChannel(Context context) );這樣就行了。這種方式每打一個渠道包只需複製一個apk,在META-INF中添加一個使用渠道號命名的空文件便可。這種打包方式速度很是快,聽說900多個渠道不到一分鐘就能打完。我親測的是我用了10秒鐘打了32個渠道包,是否是很快。
你可能會說,我看不懂上面的python代碼,那個腳本里的內容看不明白,這個不要緊。你仔細明白了原理便可,由於有人給你造輪子,咱們直接騎就能夠了。
咱們既然須要使用腳本打包,那麼相應的電腦上必須有能夠運行python腳本的運行環境。因此咱們第一步是要配置python運行環境。
本身去官網下載安裝便可,很是簡單。官網地址:https://www.python.org/
好心人已經把運行的打包腳本寫好了,而且也封裝了讀取渠道號的實體工具類。你們只須要去github上下載便可。
地址:https://github.com/GavinCT/AndroidMultiChannelBuildTool
固然在github上也有相關的使用介紹,很是簡單,一看就懂。這裏簡單說下,下載下來有個ChannelUtil.java類,裏面封裝好了獲取渠道號的方法,你只須要在啓動應用程序的地方調用友盟的設置代碼便可,好比:AnalyticsConfig.setChannel(ChannelUtil.getChannel(this))。
咱們在github上把輪子下載下來以後,你解壓文件,在PythonTool/Info/channel.txt中編輯渠道列表,沒寫一個渠道名,換行便可。
你把你已經簽名打包好的apk文件,複製到PythonTool目錄下和MultiChannelBuildTool.py這個腳本同級,直接雙擊點擊MultiChannelBuildTool.py便可完成打包。
ok,到這裏基本就講完了,講了講原理,又講了講實踐方式,鑑於別人都給你造好輪子了,因此使用起來很是簡單,趕忙去試一試吧。若是不明白的能夠留言,歡迎一塊兒交流。
參考文章:
http://tech.meituan.com/mt-apk-packaging.html
移動開發者的彙集地,公衆號「非著名程序員」,天天一篇原創技術分享和移動互聯網知識分享,微信公衆號:smart_android,頭條號和百度百家帳號都是「非著名程序員」。