Booster 是一款專門爲移動應用設計的易用、輕量級且可擴展的質量優化框架,其目標主要是爲了解決 APP 複雜度的提高而帶來的性能、穩定性、包體積等問題。java
質量優化是全部應用開發者都要面臨的問題,對於 DAU 千萬級的 APP 來講,萬分之一的崩潰率就意味着上千的用戶受到影響,對於長時間在線的司機來講,司機端 APP 的穩定性關乎着司機的安全和收入,因此更是不容小覷。android
隨着業務的快速發展,業務複雜度不斷提高,咱們開始思考:git
基於這些考慮,Booster 應運而生,通過一年多的時間不斷打磨,Booster 成績斐然。因爲目前在質量優化方面基於靜態分析的開源項目屈指可數,加上質量優化對於 APP 開發者而言門檻偏高,所以,咱們選擇了將 Booster 開源,但願更多的開發者和用戶能從中受益。github
爲了支持差別化的優化需求,Booster 實現了模塊的動態加載,以便於開發者能在不使用配置的狀況下選擇使用指定的模塊,詳見:booster-task-all、booster-transform-all。web
Booster 在進行優化的過程當中,可能須要注入一些特定的類或者類庫,爲了解決注入類的依賴管理問題,Booster 提供了VariantProcessor SPI 讓開發者能夠輕鬆的擴展,請參考:ThreadVariantProcessor.kt#L12面試
APP 的卡頓率是衡量應用運行時性能的一個重要指標,爲了能提早發現潛在的卡頓問題,Booster 經過靜態分析實現了性能檢測,並生成可視化的報告幫助開發者定位問題所在,以下圖所示:安全
其實現原理是經過分析全部的 class 文件,構建一個全局的 Call Graph, 而後從 Call Graph 中找出在主線程中調用的鏈路(Application、四大組件、View、Widget等相關的方法),而後再將這些鏈路以類爲單位分別輸出報告。性能優化
詳見:booster-transform-lint。多線程
業務線衆多的 APP 廣泛存在線程過載的問題,而線程管理一直是開發者最頭疼的問題之一,雖然能夠經過制定嚴格的代碼規範來歸避此類問題發生,可是對於組織結構複雜的大廠來講,實施起來成本巨大,而對於第三方 SDK 來講,代碼規範則有些力不從心。爲了完全的解決這一問題,Booster 經過在編譯期間修改字節碼實現了全局線程池優化,並對線程進行重命名。架構
如下是示例代碼:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) getSharedPreferences("demo", MODE_PRIVATE).edit().commit() } override fun onStart() { super.onStart() Thread({ while (true) { Thread.sleep(5) } }, "#Booster").start() } override fun onResume() { super.onResume() HandlerThread("Booster").start() } }
線程重命名效果以下圖所示:
詳見:booster-transform-thread
對於 Android 開發者來講,SharedPreferences 幾乎無處不在,而在主線程中修改 SharedPreferences 會致使卡頓甚至 ANR,爲了完全的解決這一問題,Booster 對 APP 中的指令進行了全局的替換。
詳見:booster-transform-shared-preferences。
不管是資源索引,仍是其它常量字段,在編譯完成後,就沒有存在的價值了(反射除外),所以,Booster 將對資源索引字段訪問的指令替換爲常量指令,將其它常量字段從類中刪除,一方面能夠提高運行時性能,另外一方面,還能減少包體積,資源索引(R)表面上看起來微不足道,實際上佔用很多空間,以滴滴車主爲例,資源索引相關的類就有上千個,進行常量字段刪除後,減少了 1MB 左右。
詳見:booster-transform-shrink。
爲了完全解決在 Android 7.1 中存在的bug: 30150688,Booster 對 APP 中的 Toast.show() 方法調用指令進行全局替換。
詳見:booster-transform-toast。
APP 的包體積也是一個很是重要的指標,在 APP 安裝中,圖片資源佔了至關大的比例,一般狀況下,圖片質量下降 10%-20% 並不會影響視覺效果,所以,Booster 採用有損壓縮來下降圖片的大小,並且,圖像尺寸越小,加載速度越快,佔用內存越少。
Booster 提供了兩種壓縮方案:
兩種方案各有優缺點,pngquant 的方案不存在兼容性問題,可是壓縮率略遜於 WebP,而 WebP 存在系統版本兼容性問題,總的來看,有損壓縮的效果很是顯著,以滴滴車主爲例,APP 包體積減少了 10 MB 左右。
另外,像 Android Support Library 中包含有大量的圖片資源,並且支持多種屏幕尺寸,對於 APP 而言,相同的圖片資源,保留最大尺寸的便可。以 Android Support Library 爲例,去冗餘後,APP 包體積減少了 1MB 左右。
詳見:booster-task-compression。
爲了解決 WebView 初始化致使的卡頓問題,Booster 經過注入指令的方式,在主線程空閒時提早加載 WebView。
除上以上特性外,Booster 還提供了一些輔助開發的功能,如:檢查依賴項中是否包含 SNAPSHOT 版本等等。
在 buildscript 的 classpath 中引入 Booster 插件,而後啓用該插件:
buildscript { ext.booster_version = '0.4.3' repositories { google() mavenCentral() jcenter() } dependencies { classpath "com.didiglobal.booster:booster-gradle-plugin:$booster_version" classpath "com.didiglobal.booster:booster-task-all:$booster_version" classpath "com.didiglobal.booster:booster-transform-all:$booster_version" } } apply plugin: 'com.android.application' apply plugin: 'com.didiglobal.booster'
而後經過執行 assemble task 來構建一個優化過的應用包:
$ ./gradlew assembleRelease
構建完成後,在 build/reports/ 目錄下會生成相應的報告:
build/reports/ ├── booster-task-compression │ └── release │ └── report.txt ├── booster-transform-lint │ └── release │ ├── com │ └── org ├── booster-transform-shared-preferences │ └── release │ └── report.txt ├── booster-transform-shrink │ └── release │ └── report.txt ├── booster-transform-thread │ └── release │ └── report.txt └── booster-transform-toast └── release └── report.txt
項目地址: https://github.com/didi/booster