Apk瘦身實戰總結

anAngryAnt發表於2018-07-11

一,尋找優化方向

做優化時,找到優化方向很重要,畢竟任何事情都是先有方向然後再去實踐的嘛。

先用 Analyze APK 來分析一下經過數個業務版本迭代過後的Apk

Apk瘦身實戰總結

其實網上已經有很多Apk優化的經驗了,這裡只是因地制宜地明確一下優化目標:

  1. 資源優化

    1. 圖片資源(主要優化res)

    2. 資源混淆(主要優化META-INFO/MANIFEST.TF)

    3. arsc檔案壓縮,通過將aapt編譯出來的資源二進位制檔案resource.arsc中的resource table對應塊區的值,修改為混淆後資源路徑,從而達到減少位元組數的效果。

    4. 通過網路下載非必要的本地資源(音訊、視訊等)。

  2. 程式碼方面(主要優化dex檔案)

    1. 移除重複引用的第三方庫。

    2. 移除重複程式碼塊。

    3. 基於位元組碼的dex優化 Proguard And Redex。

  3. 是否應該是用7z來對apk進行壓縮?

    1. aapt資源打包時,預設不對".jpg", ".jpeg", ".png", ".gif" 這些圖片格式的檔案進行壓縮優化。為了驗證,我們使用aapt l -v xxx.apk 指令來,未經過7z壓縮的apk,上述幾種圖片格式的檔案對應的Method都是以Stored來儲存的,根據Zip的檔案格式中對壓縮方式的描述Compression_methods可以看出這些檔案是沒有壓縮的。

      Apk瘦身實戰總結

      所以,我們可以確認,7z進行apk打包,可以帶來一定程度上的size優化。

下面會根據上面兩個方面的優化進行實戰。

二,具體實戰

1.1 優化圖片資源

  • 使用tinypng、pngquant、ImageOptim啥的圖片壓縮工具把res/ 下的所有png圖片全都進行質量壓縮一遍。如果是在Mac下,個人比較推薦用tinypng(有失真壓縮)壓一遍之後,再用ImageOptim(無失真壓縮)壓一遍,這樣可以達到比較大的壓縮效果。

1.2 & 1.3 資源混淆 & arsc檔案壓縮

  • 這裡使用到了微信的一個開源框架AndResGuard,這個框架的原理類似Java Proguard,但是隻針對資源。他會將原本冗長的資源路徑變短,例如將res/drawable/wechat變為r/d/a。這會極大程度的保護我們的資源,同時也會帶來一些優化效果。

Apk瘦身實戰總結Apk瘦身實戰總結

將AndResGuard引入專案需要注意的問題

  1. compress引數對安裝包體積影響很大。若要支援2.2,resources.arsc需保證壓縮前小於1M。

  2. keepmapping方式對增量包大小的影響影響並不大,但使用keepmapping方式有利於保持所有版本混淆的一致性。

  3. 白名單的新增:1、若想通過getIdentifier方式獲得資源,需要放置白名單中。(通過R.java的引用方式來獲取資源,儘量不要直接使用getIdentifier方式獲取資源,因 為這樣會帶來 Lint等工具的引用檢測失效 等問題。)2、部分手機桌面快捷圖示的實現有問題,務必將程式桌面icon加入白名單3、第三方庫有某些資源不能混淆,否則會crash,詳細請參考

  4. 是否與多渠道打包產生互相影響?(因為涉及到使用7z的方式來重打包apk,所以這一步是需要考慮的)

  5. 因為resources.arsc 在 APK 安裝之後仍需要被頻繁的讀取,進行壓縮後可能會帶來一些記憶體使用的上升。

2. 優化程式碼

  • 使用./gradlew dependencies 命令能夠很清晰的看到專案依賴情況(專案依賴太多我就不貼出來了),可以很容地篩選重複依賴。

  • 使用Android Studio的Inspector,去檢測無用程式碼塊,引用,定義 等等。

    Apk瘦身實戰總結

    基於位元組碼的優化

    • Android目前基於位元組碼的優化有兩種方案。

      • ProGuard

        Proguard本身就已經做了不錯的程式碼優化,它的好處不再多說,但是推薦一個開源專案

        常見第三方庫的ProGuard規則

      • Redex

        Facebook推出的一款優化位元組碼的庫,在專案上做了實現,在使用了Proguard,再使用Redex進行dex壓縮,發現兩個dex各小了0.1M,但瀏覽了一下issue,看到一些奇怪的安裝失敗的case,由於效果不太大,且這個庫不是很成熟,所以沒引入。

三,最後

隨著專案業務不斷增多,參與開發人員也不斷變多,不同的編碼習慣和水平也許會帶來一些技術債務和線上隱患,一些程式碼規範如果能夠做起來,也許能夠在程式設計師開發階段將這些債務消化掉。

  1. 使用CheckStyle或者Lint自定義規則,在開發階段使用工具進行程式碼規範檢測。

  2. 使用git-precommit,在程式碼提交階段,對commit的資源進行引用檢測、對程式碼進行質量檢測



相關文章