同步發表至 http://avenwu.github.io/2014/12/16/fast_apk_release/
前言
前陣子無意間看到美團的技術文章,一口氣讀了幾篇java、android相關的博文,寫的都非常不錯,其中有一篇講得是android管道包的問題,抱着好奇心讀完全文,文中提到了幾種管道包生成方式,從ant+for循環,maven,gradle, zip+python,随着時間的遷移,不斷在優化打包方式以滿足項目需求,結合個人經曆也确實如此。
本文接着zip+python方式打包的思路介紹一下gradle+zip+shell的打包,一來筆者不懂python,而來在之前已經寫過結合shell腳本的兩種android打包,是以對shell更感興趣。
思路
這裡所說的zip+python是筆者自己取得簡稱,因為涉及到了對zip壓縮的處理,同時用的是python中的zip接口實作.
同理gradle+zip+shell也就是利用shell指令處理zip包,以此得到我們期待的衆多apk,apk本質就是zip壓縮包,是以可以直接用标準zip處理。
此法的基石在于:
目前在apk中的META-INF目錄中增加一個無内容的空檔案後apk無需重新簽名也可以正常安裝運作
當然以後這種取巧的方式能不能行的通要看之後的android編譯工具。
- 第一步通過gradle生成一個标準的release apk,其他方式也可。
- 有了标準的apk包之後我們,拷貝一份,并在其中添加一個表示管道名稱的檔案,為了識别友善,可以定義自己的檔案名規則,本文采用xxx.channel的格式,其中xxx為管道名稱,.channel為字尾。這樣就得到了一個新的管道包。
- 修改項目代碼,動态擷取該檔案,進而得到管道名
開工
下面可以開始碼代碼了,腳本基于windows+cygwin編寫,mac下測試無誤。(下載下傳cygwin時注意需要額外勾選zip和unzip兩個工具)
完整腳本請參考buildtool.git,此處經提取關鍵部分
-
通過gradle建構的标準項目,文通過如下指令來生成apk,目标apk預設位于app/build/outputs/apk/xxx
./gradlew clean assembleRelease
-
建立存放管道包的目錄,簡單起見就叫做apk,同時拷貝已經生成的apk備用,在cygwin中經常會出現檔案的權錯誤,是以,我們需要在添加讀寫權限給apk
rm -rf apk
mkdir apk
cp build/outputs/apk/_.apk apk/pregnancy.apk
cd apk
chmod a+rw pregnancy.apk
-
生成一個新的管道包,根據目前的管道名添加檔案至apk壓縮包内,這裡用到了zip、unzip,相關用法不熟悉的google補一下吧
cp app.apk pregnancy_$1.apk && cp META-INF/pregnancy.channel META-INF/$1.channel
zip -r pregnancy_$1.apk META-INF/$1.channel
rm META-INF/$1.channel
-
仔細的你可能會問管道名在哪裡擷取,$1什麼意思?
這裡我們從預定義好的channels.properties中讀取market_channel的值,并且以“,”分割得到管道名的數組,而updateApk是我們定義的方法,方法體的内容即第三步中的代碼。
channels=(${market_channels//,/ })
for channel in ${channels[@]};do
updateApk $channel &
done
優化
這裡其實還有兩個地方可以優化
- 多核電腦可以考慮繼承多線程,文中用的是background job和多線程應該還是有差別的,最好能控制線程數,已達到最優效果。
- ant替換gradle可以減少第一個包生成的時間,目前預設情況下gradle編譯要比ant慢一些。
結語
相比較來說這種取巧的方式得到apk的速度非常快,相同配置的情況下生成越多包優勢越明顯,瓶頸隻在于磁盤讀取速率和記憶體。
經實測,90個包在windows+cygwin+8g記憶體+ssd磁盤配置下,耗時約4分半,生成第一個包的時間約為3分鐘左右,雖然沒有所謂的1分鐘900個包那麼神奇,但是已經甩開正常循環打包幾條大街了。
作者:小文字
出處:http://www.cnblogs.com/avenwu/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.