Android字節碼優化工具redex初探


 

https://mp.weixin.qq.com/s/Og2TkGrZR490h9-KO23lmw


背景

apk瘦身和啟動時間優化是移動端開發性能優化中經常被提到的兩個問題。apk瘦身的常規做法有,so文件大小優化,資源文件大小優化,代碼量大小優化等。啟動優化的常規做法有,啟動頁主題背景設置成閃屏頁圖片,一些初始化邏輯改為異步初始化等。
安居客app在以往的優化項目中也做過一些常規的apk瘦身和啟動時間優化。我們為了有更好的優化效果,近期也開始調研一些其它的優化方案,redex是其中之一,看看能否可以跳出具體業務相關邏輯,對apk本身的dex進行優化。

什么是redex

redex是facebook的一個開源工具,官方的介紹是An Android Bytecode Optimizer,Android 字節碼優化器。可以減小Android apk的大小和提高app啟動速度。
Facebook公布的性能提升數據是,包大小減少25%上下,冷啟動速度提升30%左右。這個優化空間還是比較令人心動的,但是應用到實際的項目中能帶來多少性能上的提升,以及接入成本和上線后的穩定性是需要我們使用方自己去測試和評估的。

 

redex設計簡介

1、優化基於dex
Android的編譯過程中,Java源文件編譯成class文件,再和三方庫一起轉換為dex文件。redex的優化是針對dex文件做優化。基於dex優化相對於基於源碼優化的優點有:
 1)可以最大限度的進行全局、類與類之間的優化;
 2)可以類似於C語言編譯過程中的link,對代碼進行整合;

2、優化過程的管道設計
優化過程被設計成一系列獨立“優化插件”,在優化管道中可以自由組合,即插即用。這樣做的目的有:
 1)可以靈活加入新的優化項插件;
 2)各優化插件間互不影響,可以多個優化插件並行開發;
 3)支持使用者通過配置,選擇需要的優化項;



 

 



優化管道設計

 

redex的優化方法

根據官方文檔的說明,主要的優化項有以下幾點:1、混淆和壓縮
類似Android中的proguard,將字節碼中的類名、方法名等替換成簡短的字符串。2、內聯函數
functionA->functionB->functionC,內聯后變成functionA(包含functionB代碼)->functionC,減少函數調用時間。3、刪除代碼
類似於標記回收算法,從某些入口函數可以遍歷標記出可以訪問到的方法,最后未標記到的方法可被移除。理論比較簡單,但在 Android中還有反射,或者資源文件中對代碼的引用等特殊情況需要考慮到。4、基於反饋的class分布
也就是可以對dex進行重組,根據使用方提供的app啟動時加載的類序列配置文件調整dex中類的順序,把app冷啟動時需要加載的類,放到dex前部。5、刪除接口
刪除只有一個實現類的接口,直接使用實現類。
6、刪除metadata
dex文件中的一些元數據在運行中並不會使用到。所以可以用dex中已有的字符串代替java源文件引用,刪除運行時使用不到的注解。

如何使用

1、編譯&安裝
redex工具是需要自己編譯安裝的。我是macOS系統,編譯的過程就踩了各種坑,gcc版本,Xcode Command Line Tools版本,各種依賴庫等,就不再贅述。按照文檔一步步來,遇到問題,解決問題就好,整個編譯過程花費1個小時左右。

2、配置

redex的默認優化項包括了上個章節列舉的優化方法。


 

 



默認優化配置項

3、Interdex優化項
Interdex這個進階優化項是需要使用方額外配置的。優化的方法是根據app冷啟動時需要加載的類,調整dex中類的順序。此項配置需要提供app啟動時加載的類序列。redex中提供了python腳本,分析app啟動時dump下來的hprof文件,得到類序列。實際在使用的過程中各種報錯。翻看issue,發現這個腳本應該很久沒有維護了。放棄使用腳本,通過替換掉app的ClassLoader來獲取app啟動時加載的類。



 

 



替換ClassLoader

4、簽名和對齊

redex處理后的apk,需要重新簽名,zipalign對齊。

 

對安居客app的優化結果

Facebook公布的性能提升數據是,包大小減少25%上下,冷啟動速度提升30%左右。應用到具體的項目上,這個優化結果是什么呢。經過測試,對安居客app做了默認優化+Interdex優化后,包大小以及冷啟動速度優化如下:

1、包大小
debug apk包大小減小10%,release apk包大小只減少100KB。悲催的發現,redex對包大小的優化效果並不明顯,尤其是混淆后的release apk,優化效果更是非常小(100KB左右)。

 

2、啟動速度
測試發現4.X系統上冷啟動速度提升20%左右,5.0+系統上冷啟動速度沒有明顯變化(測試手機樣本有限,后續繼續研究)。從結果上看,4.X系統上的冷啟動優化較為明顯。但是線上4.X用戶的占比非常少。所以這個優化的結果也並不令人滿意。
猜測4.X系統上冷啟動速度提升較大的原因是,Interdex把啟動時需要的類都前置到主dex中。這樣apk安裝的過程中,dexopt時,主dex中滿足pre-verify的類會增多。安裝時做了校驗和優化,啟動時減少了類加載的時間。但是5.0+系統的Art虛擬機采用了新的方式,所以對啟動速度沒有明顯的優化效果。

總結

redex的接入成本比較高,這個成本包括對現有打包流程和熱修復流程的影響,上線后的穩定性,以及問題排查的難易程度。接入成本對比優化結果看,接入是低性價比的,所以目前是放棄直接接入到項目中使用的。
redex雖然接入到成熟的app中有很多坑,但依然是一個很好的開源項目。通過調研redex,發現其中單個的優化項可以再去發掘應用,比如Interdex優化項,就可以在項目打包編譯的過程中,修改dex分包邏輯,把app冷啟動時需要加載的類,放到主dex中。

    

參考文獻

1、redex 官方文檔:

https://fbredex.com/
2、Open-sourcing ReDex: Making Android apps smaller and faster:

https://engineering.fb.com/android/open-sourcing-redex-making-android-apps-smaller-and-faster/
3、Optimizing Android bytecode with ReDex:

https://engineering.fb.com/android/optimizing-android-bytecode-with-redex/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM