閱讀797 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android熱修複

我們部門有很多Android的能力SDK,被很多App(約1000個)集成。每次SDK有微調發布新版本後,App集成需要花上1-2個月時間,很多時候SDK團隊和App團隊雙方都很痛苦。16年10月份,Boss叫搞一個Android的熱修複功能。神奇的是,居然讓我一個從未搞過Android的人來負責(看來我在老板心中 隻能充當救火隊員)。我在16年12月完成了第一個版本的實現,後麵詳細針對200多種機型的調試,就交給其他同事去了。 最近看見已在部門幾個產品推廣該功能了,想想還是記錄下當時實現的思路。

         當時首先調研了幾個公司的App熱更新方案(沒辦法,當時市場上沒有針對SDK的熱修複,僅找到針對App的)

l  阿裏百川的Andfix

n  優點是:能針對方法級別的更新,而且是真正的熱修複-不需要重啟App

n  缺點是:1)使用了Java的newInstance()去構造對象,所以不支持帶參數的構造函數 2)也不支持新增類和類字段 3)因為該方案本持是在native C++層替換函數指針來實現方法的“熱替換”,牛是很牛了,但據說導致崩機率高。

n  結論:不適合我司的場景,PASS掉

n  備注:在17年1月推出了AndFix的2.0新版本,據說有本質的提高。但因為沒有開源,隻能圍觀一下。

l  QQ的HotFix(開源版本叫Nuwa)

也就是大家熟知的Classloader方案。重啟App後更新。

n  優點是:該方案提穩定性是最好的,補丁生效率是最高的。但是對補丁大小有嚴格限製。

n  缺點是:開源的Nuwa程序,實際使用後程序不是很穩定,在部分機型上老是崩潰。一旦補丁升級過多,會導致App在運行時效率低下。

l  微信的Tinker

整個更新過程和QQ的方案類似,但本質卻完全不同。Tinker在客戶端在收到補丁後,將用原Apk文件+補丁做一次合成,形成新的APK文件,再基於新的APK文件運行程序。

n  優點是:不受限補丁更新次數,不受限於熱修複本身,一旦程序啟動後,對性能無影響。

n  缺點是:啟動程序(比如微信)時,因為有合成動作,占用內存較多。

l  美團的熱修複

在所有Class的所有Method中自動插樁一段代碼。這段代碼包含了更新的邏輯。

n  優點是:是基於Java的原理實現,而非Android本身原理,原理更加通用和簡單。

n  缺點是:增加APK包體大小,直接導致部分DEX文件超過65535 Method總數的限製。盡管後續做了優化,但個人感覺太過簡單粗暴。

n  結論:PASS掉

l  攜程的插件化方案

把每個SDK做成APK格式,由主程序加載所有APK文件。

n  優點是:很符合我司SDK更新的場景,而且能同時更新SDK的UI、Java代碼、so庫。看起來很完美。

n  缺點是:老板說,SDK熱修複方案要對App層無感知。但攜程的插件化方案需要對App框架進行改造。1000個App,得改到啥時候啊。

n  結論:最開始本來想采用這套方案來著,後麵也隻有揮淚PASS掉。

l  我司其它團隊的土方法:

1)      去掉SDK的UI層,直接將SDK的界麵通過純Java代碼實現,界麵中涉及的圖片,通過網絡在線加載

2)      把Java層切成兩部分:接口和核心邏輯,分別單獨打包。接口層初始化時負責加載核心層的Java包。

        最後基於種種考慮,采用了QQ和微信的混合方案, 客戶端熱修複的底層實現,使用Nuwa中代碼(加載dex包部分);補丁的生成方案使用微信的dexDiff算法。

       缺點就是:不能更新SDK的UI層,僅支持更新SDK的Java層和so庫。 主要原因是SDK本身的限製,畢竟不是App,拿不到相應的係統權限。

      大體方案如下圖所示:

35ac96286790057657e26a67da8ad7833307c63470274ec8d07eeeadc12224e97d55a97888be2764


     本次介紹就到這裏。抽空再介紹一下實際操作中,遇到熱修複不生效和崩機時的回退方案。

最後更新:2017-10-26 09:03:31

  上一篇:go  淺談java的方法覆蓋與變量覆蓋
  下一篇:go  php麵向對象(含義)