Android外掛化的歷史及熱門專案對比

weixin_34116110發表於2017-09-21

轉載自http://www.chopiter.com/android_plugin/

本文旨在梳理Android外掛化的歷史及對比各家技術能解決的問題,對比出優缺點。既是Android外掛化的總結,又可以當做外掛化入門的引導。本文不對技術細節過多探討,細節方面會有相應的參考連結。

一、歷史
外掛化的歷史已經有很長一段時間了,各種大大們也介紹過外掛化相關的歷史,比如:

包建強的:Android外掛化:從入門到放棄
T大:Android 外掛化 動態升級
張濤:Android 外掛化的 過去 現在 未來

按照時間維度來看,整理成以下表格:

329563-6c5bbe99b5d6c0f5.jpeg
android_plugin

AndroidDynamicLoader
AndroidDynamicLoader的作者是大眾點評的屠毅敏,應該是最早的動態載入實現方案了。作者在介紹這個框架時形容宿主App就好像瀏覽器,但它載入的並不是網頁,而是執行在Android系統上的外掛。這個方案主要是在外掛中使用Fragment,在宿主中使用Activity去動態載入外掛中的Fragment。
github連結:https://github.com/mmin18/AndroidDynamicLoader

23Code
23Code並不是一個開源的專案,它是一個完整的apk。在應用市場可以下載得到,它內部展示了一些有趣的動效,通過下載的方式,可以直接執行起來,這就是外掛化的真實案例。

Altas
altas是阿里的伯奎分享出來的一個外掛化的方案。
分享視訊連結:http://v.youku.com/v_show/id_XNTMzMjYzMzM2.html
對應的PPT:http://club.alibabatech.org/resource_detail.htm?topicId=84

這裡的分享主要是將一些思路,業務方面的場景,解決的問題。後來github上有了對應的開源專案叫OpenAltas,後改名ACDD。
ACDD的連結:https://github.com/bunnyblue/ACDD

官方對這個庫的說明是非代理Android動態熱部署框架,而且在視訊介紹中,伯奎也講到,這個方案,就是把宿主當做一個容器,動態載入對應的外掛。視訊中也有講到,要做到讓外掛無感知地執行在這個容器中,需要hook很多系統層面的東西,比如:ActivityThread,LoadedApk,ContextImpl,PackageParser,ActivityManagerNative等,即當外掛需要系統的服務來提供對應功能的時候,將這個行為攔截掉,宿主就可以在外掛和Android系統中間做些手腳了。在當時,Altas是最為先進外掛化技術了。為淘寶客戶端提供了很多載入其他業務外掛的能力。

Dynamic-load-apk
Dynamic-Load-Apk簡稱DL,這個開源框架作者是任玉剛,他的實現方式是,在宿主中埋一個代理Activity,更改ClassLoader後找到載入外掛中的Activity,使用宿主中的Activity作為代理,回撥給外掛中Activity所以對應的生命週期。這個思路與AndroidDynamicLoader有點像,都是做一個代理,只不過Dynamic-load-apk載入的外掛中的Activity。
專案地址:https://github.com/singwhatiwanna/dynamic-load-apk
專案說明:http://blog.csdn.net/singwhatiwanna/article/details/40283117

DroidPlugin
DroidPlugin是張勇實現的一套外掛化方案,它的原理也是Hook客戶端一側的系統Api,可能與Altas所Hook的點不同,細想應該是基本相同的。
專案地址:https://github.com/DroidPluginTeam/DroidPlugin

專案中DOC資料夾有很多關於專案的講解說明。
張勇本人對DroidPlugin的講解:http://www.infoq.com/cn/presentations/the-realization-principle-and-application-of-droidplugin?utm_campaign=rightbar_v2&utm_source=infoq&utm_medium=presentations_link&utm_content=link_text
維術對這個框架的講解:http://weishu.me/2016/01/28/understand-plugin-framework-overview/

維術的這幾篇blog很詳細滴講解了DroidPlugin是如何實現四大元件的外掛化的,還有幾篇有規劃但是沒有寫的方面,希望後面能補全。

VirtualApp
VirtualApp作者是高中生羅迪,據說這個Android大牛初三的時候就開始研究雙開、外掛化的技術,相當了不起。專案的思路與DroidPlugin相似,不過他沒有提供Service的代理,而是使用ContentProvider來代替Service在宿主中作為真正的執行體。
專案地址:https://github.com/asLody/VirtualApp

DynamicAPK
DynamicAPK是攜程推出的動態載入方案
專案說明:http://www.infoq.com/cn/articles/ctrip-android-dynamic-loading
專案地址:https://github.com/CtripMobile/DynamicAPK

與ACDD一樣修改了aapt,使得外掛與宿主的資源不會出現相同id的問題。

熱修復
外掛化技術的演進,帶來了相關的熱修復技術。有代表的熱修復技術有:

  1. QQ空間的超級補丁技術
  2. 微信Tinker
  3. 阿里的AndFix

QQ空間和微信的Tinker的細想很相近,都是在查詢類的之前,將外掛的dex插入原有dex之前,使得能夠載入的是最新插入進來的dex中的class。從而達到修復原有類的問題的目的。它們並沒有在Github上開源,賈吉鑫根據這個思路做出了Nuwa開源道github上,之後又有很多類似的開源專案。阿里的AndFix與這種思路不同,它採用的是方法替換的思路,在native層,把這個方法實現體的指標替換為修復後的方法。

這兩種方案其實都有很多弊端,QQ空間的類替換方法,不能即時生效,patch如果修復的地方比較多,會影響啟動時間。而AndFix,則只支援方法層面的替換,不能使用未import過的類,不能替換整個類檔案。

美團有一種叫做Robust的熱修復方案
連結:http://tech.meituan.com/android_robust.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

它應該是效能與修復場景最好的一種了。它的思想與InstantRun一樣,在編譯時動態地為每個類中的每個方法插樁,每個方法判斷是否有外掛被載入,有的話直接執行外掛中的方法。

相關文章