1. 程式人生 > >當我們在談論multidex65535時,我們在談論什麽

當我們在談論multidex65535時,我們在談論什麽

延遲 原則 sta erl tid 跳轉 一起 通過反射 倒置

本文來自網易雲社區


作者:鄭文


首先我們並不在討論車牌號.本文盡量避免談論重復的技術點,只探討一下multidex提供給我們的技術啟示。

原理

multidex技術原理可以分成兩個部分:

  • 在app啟動時,通過Multidex.install api,擴展ClassLoader的dexElements數組來存儲所有dex,這個流程會根據android sdk版本的不同做不同的處理,整個流程完全通過反射完成。

  • 編譯過程中的分包機制,將app中的class以某種方式將class分布在多個dex中

Multidex.install

從multidex的原理,很容易想起目前比較流行的一個代碼熱修復方案策略。安卓App熱補丁動態修復技術介紹

,qzone的技術思路在社區誕生了很多技術框架,其中知名度最高的就是Nuwa。但客觀的說,nuwa這個項目是完全達不到產品release的要求。在調研完所有同技術路線開源框架後,我們決定造個能應用在線上產品的輪子。

我們的解決方案

  • 使用Transform API進行bytecode的植入,支持高版本gradle

  • 編譯流程的優化,減少了人工幹預的過程

  • 支持補丁包的簽名驗證,避免被惡意hook

  • 兼容網易安全部門的加殼方案

  • 支持ART模式:在art模式下,應用補丁包可能導致地址錯亂,解決方案是將直接引用修改class的相關類都打包進行補丁包,這是目前其他開源方案沒有做的

MultiDex存在的問題

MultiDex機制的出現本身是為了避免出現app 65535問題的出現,但隨著業務邏輯的增長,以及不合理的模塊劃分,導致main dex的方法數也超出了65535,這就導致了main dex capacity exceeded異常。

同時,Multidex的接入額外還會對app的啟動性能造成影響。Multidex在install時需要加載dex,首次啟動時還需要做odex的轉換,而這些都是在ui主線程中完成。 根據 Carlos Sessa的測試,啟用multidex後,4.4或以下的設備,app的啟動時間平均會增加15%的時間,更嚴重的情況,甚至在啟動時候會出現了黑屏。

目前部分app采取的策略是,放棄掉Multidex的,而轉為插件化的架構。通過將非核心模塊的lazy load,來達到啟動速度的優化,但我們需要明確的是,並不是所有app都似乎插件化架構,為了實現啟動加速或熱更新將本耦合的業務邏輯硬生生拆解才是本末倒置。

解決方案

Multidex異步化

在Android的性能優化中,最常見的思路就是異步化,減少UI線程的工作。在應用的交互層面上,app啟動時,幾乎所有app都會有一個SplashActivity。在界面上展示歡迎頁,在後臺進行初始化的業務邏輯。這就給我們一個啟發,我們可以將系統的初始化邏輯,延遲到我們的業務初始化時間點上。

更加具體的方式是,我們可以將Multidex.install異步化,保證主線程的正常進行,待加載完成後通知SplashActivity跳轉到真正的業務主界面。

在MultiDex加載的異步化之後,我們可以進行第二步:main dex大小的精簡。

Multidex分包原理介紹

Multidex會在入口Application的attachBaseContext,加載second dex,因此multidex分包的基本原則是:保證app啟動需要的class放置在main dex上。在gradle 1.5以上,multidex通過CreateManifestKeepList和MutidexTransform完成,分包過程可以分為三步:

  • 生成manifest_keep.txt

CreateManifestKeepList會解析出AndroidManifest.xml中所有的組件類:包括Activity、Service、Receiver以及ContentProvider,這些類將會和Application入口類一起放在build/intermediates/multi-dex/{flavor}/{buildType}/manifest_keep.txt中

  • 生成maindexlist.txt文件

MutidexTransform會查找manifest_keep.txt中所有類的直接引用類,具體的方式是遍歷類的所有字段類以及方法,查看方法的參數和返回值的類型,將其放保存在maindexlist.txt

  • 生成main dex

當我們在談論multidex65535時,我們在談論什麽