天天看點

Android 淺談插件化

一、什麼是插件化

Android 淺談插件化

有對比更形象,以元件化為對照

元件化開發:将一個app分成多個子產品,每個子產品都是一個元件(Module),開發的過程中我們可以讓這些元件互相依賴或者單獨調試部分元件等,但是最終釋出的時候是将這些元件合并統一成一個apk

插件化開發:将整個app拆分成很多子產品,這些子產品包括一個宿主和多個插件,每個子產品都是一個apk(元件化的每個子產品是個lib),最終打包的時候将宿主apk和插件apk分開或者聯合打包。

二、插件化的優勢

1、解耦,宿主和插件分開編譯:編譯時隻需要編譯宿主app,插件app是在編譯好後下發到宿主app裡的。

2、并發開發:宿主app什麼時候釋出版本跟插件app什麼時候開發完沒有關系,宿主app隻要開發完并且為插件app提供一個入口就可以了。

3、動态更新插件:插件app在開發完後下發到宿主app裡,點選相應的入口就可以跳轉到最新版的插件app了。

4、按需下載下傳子產品,降低app體積

5、解除單個dex方法65535的限制

三、插件化的基礎

1、反射:運作時,可以通過名稱,獲悉其完整構造,并生成其對象實體、或對其fields設值、或喚起其methods,這樣的機制稱之為反射。關于反射,可以檢視 -> Android 反射

2、Hook:安卓面向切面(AOP)程式設計的基礎,可以讓我們在不變更原有業務的前提下,插入額外的邏輯.

 Hook 的選擇點:盡量靜态變量和單例,因為一旦建立對象,它們不容易變化,非常容易定位。

Hook 過程: 

•尋找 Hook 點,原則是盡量靜态變量或者單例對象,盡量 Hook public 的對象和方法。

•選擇合适的代理方式,如果是接口可以用動态代理。

•偷梁換柱——用代理對象替換原始對象。

3、類加載機制:

幾個重要加載器:BootClassLoader,PathClassLoader和DexClassLoader

Android 淺談插件化

DexPathList内部定義了dexElements,專門記錄已加載的dex

四、幾種插件化架構對比

Small VirtualAPK RePlugin Atlas
支援四大元件 隻支援Activity 全支援 全支援 全支援
元件無需在宿主manifest中預注冊 無需 無需 無需 需要
插件可以依賴宿主 可以 可以 輕度依賴 可以
支援PendingIntent 支援 支援 支援 --
相容性适配 --
接入難度

五、App插件化原理

Android 淺談插件化
Android 淺談插件化

對于宿主工程來說,在加載插件工程後,将插件dex插入到宿主工程的dexElements集合後面即可,在之後的運作中就可以按需加載插件中的class。需要注意的是,插件中的類不可以和宿主重複 。

Android 淺談插件化

1、Activity

跟進startActivity的調用流程,會發現其最終會進入Instrumentation的execStartActivity方法,然後再通過ActivityManagerProxy與AMS進行互動。

Android 淺談插件化

Hook AMS:基于動态代理技術實作ActivityManagerProxy,以實作攔截ActivityManagerService的方法調用,然後利用反射将ActivityManagerNative執行個體替換掉ActivityManagerNative的gDefault成員。

Android 淺談插件化

Hook Instrumentation:擴充Instrumentation以實作對Activity啟動過程的控制,然後使用反射将擴充Instrumentation執行個體替換ActivityThread對象原來的Instrumentation對象。

Android 淺談插件化

1) 替換

    繞過Android對啟動Activity的限制。

    提前在主APP中占有坑位,Activity必須先在AndroidManifest注冊,否則不能被startActivity。具體實作為利用hook的VAInstrumentation攔截Instrumentation的execStartActivity方法,并在該方法内将待啟動的插件Activity名稱改 為StubActivity。

2) 還原

       繞過系統對插件Activity的合法校驗後,将StubActivity名稱改回原來的名稱,以使得在Instrumentation.newActivity時執行個體并啟動正确的目标Activity。

Android 淺談插件化

2、Service

動态代理AMS,攔截service相關的請求,将其中轉給Service Runtime去處理,Service Runtime會接管系統的所有操作

插件Service的啟動/關閉基于被Hook的AMS,VirtualAPK在攔截到start/bind/stop/unbind Service的調用後,會執行ActivityManagerProxy的invoke方法,之後控制流程和資料會轉交給ServiceDelegate對象,之後ServiceDeletegate會判斷待啟動的Service是本地服務還是遠端服務,如果是本地服務,VirtualAPK會反射調用Service相應生命周期的方法;如果是遠端服務,VirtualAPK先将目标插件apk加載進來,然後再反射調用目标Service的生命周期方法。

Android 淺談插件化

六、插件化的幾個重要優勢

體積:按需接入需要的插件,可以達到減少體積的作用

更新:插件獨立開發,通過下發實作低成本和低頻解除安裝重裝

版本:同個功能插件可以打包生成不同版本,下發時候按版本選擇合适的插件apk,可以實作多版本的相容

七、插件化風險點、

1、個别屬性由于插件化實作方式會造成不支援。

2、Android P,禁止調用私有API(經過@hide修飾的方法),在适配上可能需要費些功夫

3、VirtualApk近一年未更新,目前隻支援到com.android.tools.build:gradle:3.1.0.

注:以上内容主要來自之前做的技術分享ppt整理,細節可能不夠詳實。

感謝一下部落格 -> 

https://www.jianshu.com/p/a7b36d682b6f

https://blog.csdn.net/lmj623565791/article/details/75000580

https://www.cnblogs.com/tgltt/p/9542193.html

繼續閱讀