開源 | BoostMultiDex:挽救 Android Dalvik 機型APP升級安裝體驗

現代 Android APP 的代碼量通常都比較大,很容易就會帶上多個 DEX 文件。Android 低版本的設備採用的 Java 運行環境是 Dalvik 虛擬機,如果含有多個 DEX 想要在這些設備上正常運行,就需要使用官方的 MultiDex 方案。MultiDex 需要對 APK 內的原始 DEX 文件做 ODEX 優化,所以執行時間過於漫長,這就會使得安裝或者升級後首次 MultiDex 花費的時間很久。

抖音自研的 BoostMultiDex 方案,可以大幅改善原有的 MultiDex 耗時。並且,不同於目前業界所有優化方案,我們是從 Android Dalvik 虛擬機底層機制入手,從根本上解決了安裝後首次執行 MultiDex 耗時過長問題。

之前已經發布過兩篇文章,詳細介紹了 BoostMultiDex 的實現原理:

抖音 BoostMultiDex 優化實踐:Android 低版本上 APP 首次啓動時間減少 80%(一)

抖音 BoostMultiDex 優化實踐:Android 低版本上 APP 首次啓動時間減少 80%(二)

其中也展示了這一優化帶來的顯著效果:

開源地址

Github 項目地址:

https://github.com/bytedance/BoostMultiDex

實際表現

我們之前的文章裏面只是提到了技術分析和一些優化數據,爲了讓大家更加直觀地感受 BoostMultiDex 帶來的明顯效果,這裏就來看下我們項目中實際表現是怎樣的,以今日頭條 APP 爲例,左邊是 BoostMultiDex,右邊是原始 MultiDex:

https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&auto=0&vid=wxv_1355562813275815937

可以明顯看到頁面打開時間的差距,左邊的 BoostMultiDex 方案有非常顯著的優化,界面在短暫等待後就立即展示出來了,而右邊的原始 MultiDex 方案要等待半分鐘左右才能展示界面。

當然,這個優化帶來的實際體驗提升情況,還要看結合每個 APP 自身。除了加載多 DEX 的時間,APP 啓動階段還有大量自身業務邏輯,而這塊的耗時是相對固定的。這屬於業務層面的啓動優化問題了,應當儘量減少啓動階段執行那些不會立即使用的模塊加載。 而 BoostMultiDex 的接入成本極低,能保證僅替換一行代碼,就達到立竿見影的效果。

快速接入

本方案的使用和官方 MultiDex 基本上是一致的,只需兩步即可接入。

首先,在 build.gradle 的 dependencies 中添加依賴:

dependencies {
... ...
    implementation 'com.bytedance.boost_multidex:boost_multidex:${ARTIFACT_VERSION}'
}

然後,與官方 MultiDex 類似,在 Application.attachBaseContext 的最前面進行初始化:

public class YourApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);

        BoostMultiDex.install(base);

... ...
    }

這樣就完成了所有工作了。立馬編譯運行,看看是不是 APP 首次冷啓動變得健步如飛?

一些補充

之前的兩篇文章中已經對 BoostMultiDex 方案的技術實現細節有詳細敘述,主要涵蓋了以下幾個
技術要點:

  1. 利用系統隱藏函數,直接加載原始 DEX 字節碼,避免 ODEX 耗時
  2. 多級加載,在 DEX 字節碼、DEX 文件、ODEX 文件中選取最合適的產物啓動 APP
  3. 單獨進程做 OPT,並實現合理的中斷及恢復機制

此外,這裏再補充一些說明。

主 DEX 相關

首先,和 MultiDex 一樣,BoostMultiDex 的所有類都是需要打入主 DEX 裏面的,默認情況下,由於 Application 內有直接引用 BoostMuliDex,Gradle 就會自己幫我們自動打入主 DEX。但如果由於某些罕見的異常情況沒有打入,我們就需要自己額外做這個處理,強制把com.bytedance.boost_multidex包中的所有類打入到主 DEX 裏。

對於 ODEX 優化進程的處理

ODEX 優化進程是在名爲:boost_multidex的進程中的,他會開啓一個OptimizeService後臺服務做優化,當然,所有進程都會走到Application裏,Application裏包含了很多其他進程共有邏輯,對於 ODEX 優化進程而言,這些邏輯是不需要的,因此,我們提供了一個BoostMultiDex.isOptimizeProcess方法,便於使用者自行判斷,直接跳過這些無關業務邏輯。由於整個 BoostMultiDex 都在主 DEX 中,因此對於 ODEX 優化進程,BoostMultiDex.install也是不需要的。當然不做這個判斷也關係不大,只是會額外執行一些無用代碼,有些許效率損失。

Android 4.4 的 ART 機型

Android 4.4 機型同時集成了 Dalvik 和 ART 兩套虛擬機,一般廠商的默認出廠機型都是採用 Dalvik 的。由於本方案只針對 Android Dalvik 機型有優化,對 ART 是沒有效果的,因此,如果遇到某個機型優化效果差異不大,可以先看下是什麼機型,並從輸出日誌可以看出是什麼原因沒有走到優化邏輯。

部分 Dalvik 內部數據結構有偏移的機型

我們的方案中涉及到對 Dalvik 虛擬機內部DvmDex結構體做設置,而如果廠商對這些結構做了特殊修改,就會導致設置到錯誤的偏移。這種情況目前看來還是極少的,僅在我們在線上大面積灰度過程中發現了一些 HTC 機型有修改這個結構,對此我們已經做了修正。這裏也提前說明,避免大家在看到這塊代碼的時候遇到困惑。

最後

當然,技術上說的再多,不如看實際收益。目前,BoostMultiDex 已經在抖音億級全球用戶上驗證通過,可以說涵蓋了各種複雜情況的 Android 機型,目前業界其他大型 APP 都很難涉及到如此廣泛的規模。由此,我們也解決了各種奇怪的兼容性問題,最大程度上確保了技術方案的穩定性。

對於項目的開源代碼,我們保證, 和抖音自身使用的代碼完全一致 ,直接開箱即用,避免大家接入後還要自己踩一遍我們曾經遇到的坑。如果在實際使用過程中如果遇到什麼問題,我們也希望大家及時提出,一起貢獻代碼,共同將 BoostMultiDex 打造得更加穩健高效。

目前, 抖音 Android 基礎技術團隊仍在上海、北京、杭州、深圳大力招人 ,如果你也同樣對技術充滿熱情,同樣追求極致優化,想要與我們共同建設億級用戶全球化 APP,那就歡迎進入字節跳動招聘官網查詢抖音 Android 相關職位,也可以聯繫 [email protected] 諮詢相關信息或者直接發送簡歷內推!

本文轉載自公衆號字節跳動技術團隊(ID:toutiaotechblog)。

原文鏈接

https://mp.weixin.qq.com/s/0gtkc7IQdhKjFxrHCuNZwQ

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章