1. 程式人生 > >Android外掛化原理和實踐 (一) 之 外掛化簡介和基本原理簡述

Android外掛化原理和實踐 (一) 之 外掛化簡介和基本原理簡述

1 外掛化簡介

Android外掛化技術是一種這幾年間非常火爆的技術,也是隻有在中國才流行起來的技術,這幾年間每每開發者大會上幾乎都會提起關於外掛化技術和相關方向。在國內各大網際網路公司無不都有自己的外掛化框架。

外掛化技術到底是什麼?

其實很好理解,像某些App中整合了很多功能點,而一些不是非常必要的功能一般會在使用者點選功能入口時才會通過網路下載一個像補丁的東西,然後將其載入起來,使功能可用。而這種通過補丁式免安裝、熱載入的技術就是外掛化技術。外掛化技術需要清楚區分兩個概念:宿主和外掛。宿主是指我們的主APK包,它是像正常APK一樣需要安裝的; 而外掛理論上它也是一個APK包,但是它是被宿主載入起來整合到宿主中的像補丁一樣的東西。它們的關係就像Windows中exe檔案和dll檔案一樣。

為什麼需要外掛化?

在我們日常開發版本迭代中,產品需求如滾雪球般使得工程程式碼越來越龐大,也開始難以維護。新功能以及Bug修復想要在最短時間釋出版本到各大市場的到達率低,使得App更新週期非常得長。這時使用外掛化的好處就非常明顯。因為外掛化可使功能模組程式碼解耦,使得能夠很好地規範工程程式碼和並行開發以及提高發版的靈活性。在使用者手機環境中只要有網路情況下使用App就能夠下載外掛補丁快速到達和動態載入外掛程式碼達到免安裝即時升級的效果。而且在效能方面考慮,因為工程程式碼越來越多,也能有效地解決DEX檔案方法數達65535的問題,抽離程式碼後,安裝包大小也相應得到控制。在使用者環境中,也可按需載入邏輯,從而也更有效地控制記憶體。

什麼情況需要外掛化?

對於核心底層模組,一般不建議進行外掛化,就算要外掛化也得在App起來後第一時間將其載入起來使得生效;

對於核心業務模組,可進行外掛化,但也要在最初時載入起來;

對於非核心業務模組,建議進行外掛化,使用者可以聯網後下載外掛按需載入。

模組功能開發初期要反覆新增或修改四大元件情況下不而進行外掛化,因為大多外掛化框架對四大元件支援並不完美,一般情況下都是先在宿主中AndroidManifest中先有宣告元件才能夠在外掛中實現使用,所以在模組功能開發成熟後再考慮外掛化。

2 外掛化簡史

國內外掛化框件可以稱得上是五花八門,各有各的流派,下面我們來簡單認識一下一些比較出名有代表性的外掛化框架:

2012年7月,大眾點評的屠毅敏釋出了第一個Android外掛化開源專案:AndroidDynamicLoader。這個外掛化的特點在於整個專案中只有一個Activity,它通過動態載入外掛中的Fragement來實現頁面的跳轉。而外掛資源的載入就是通過反射呼叫AssetManger的addAssetPath方法來處理的。由於它是最古老的外掛化框架,而且是基於Eclipse和Ant來實現的,因此在今天AndroidStudio和Gradle盛行的今天顯得有些過時。

2013年3月,淘寶客戶端的伯奎的一個技術分享,專門介紹了Atlas外掛化框架,分享中包括了對Android系統底層幾個重要類的Hook介紹、增量更新、降級、相容等技術。

2014年3月,《Android開發藝術探索》作者任玉剛開源了dynamic-load-apk外掛化框架,些框架並沒有對Android系統底層程式碼進行Hook,而是通過代理形式建立一個ProxyActivity類來進行分發啟動相應的Activity,最有特式的語法就是that關鍵字。

2014年11月,houkx在GitHub上釋出了外掛化專案android-pluginmgr,此框架是最早提出在AndroidManifest檔案中註冊一個替身StubAcitivty來欺騙ActivtyManagerService,來解決外掛Activity的支援。

2015年4月,淘寶的Atlas框架也就是OpenAtlas專案釋出在Github上,並改名為ACCD。它是基於OSGI框架的。在資源方面,裡面提出了通過修改重新生成aapt命令來支援外掛中資源id的自定義,使得很好地支援外掛資源和宿主資源合併後衝突的問題。它也對Android底層的Instrumentation的execStartActivity方法做了Hook,來實現Activity的外掛化。

2015年8月,360手機助手的張勇公開了他們家手機助手使用的外掛化框加DroidPlugin。些框架有一個牛逼的地方就是對四大元件很好地支援,以至它可以將任意的App當成外掛來載入到它自己的宿主中去。它的內部Hook了很多Android不同版本的系統底層程式碼,所以也是一個相當複雜的外掛化框架。

2015年11月,林光亮釋出了Small外掛化框架,此框架特點是把外掛的ClassLoader對應的dex檔案塞入到宿主的ClassLoader中,從而使宿主可載入外掛中任意類,在資源方面也是通過反射呼叫AssetManger的addAssetPath方法來處理的,但它沒有使用修改aapt來解決資源衝突,而是在生成外掛R.java和resources.arse這兩個檔案後,再把它們所有資源字首進行修改。

2016年8月,掌閱推出Zeue

2017年3月,阿里推出Atlas

2017年6月,360手機衛士的RePlugin

2017年6月,滴滴推出VisualApk

……

3 根本問題和原理簡述

雖然說外掛化技術框架五花八門,但它們所解決的事情都是一樣的,就是怎樣支援或者說怎樣更好地支援宿主載入使用外掛的邏輯。而這個支援問題其實就是要攻克以下最根本的三點技術:

1、宿主和外掛中如何相互呼叫程式碼

2、宿主載入外掛後如何解決資源讀取問題

3、在外掛中對四大元件怎樣更好地支援

解決了這三點後,剩下的事情就是錦上添花了。我們從上面外掛化簡史中可以大概認識到一些外掛框的特點,綜合一下解決方案。比如要解決第1點程式碼相互呼叫的問題,就可以把外掛的ClassLoader對應的dex檔案通過反射塞入到宿主的ClassLoader中,然後在宿主或外掛中可以通過反射來實現相關類的呼叫; 而第2點資源問題,就是通過反射呼叫AssetManger的addAssetPath方法來合併資源,至於資源衝突就修改aapt就可以解決好了;最後一點外掛中使用四大元件是最為麻煩的事情,我們可以通過that關鍵字的代理形式實現,也可以通過Hook系統底層程式碼來盡理更好地實現,也可以不實現,提前在宿主中宣告相當多的空的元件來待用。其實都行,所以我們在決定對工程下刀外掛化之前,就要認真考慮結合實際情況來選擇哪一種的外掛化技術才是適合自己的了。