插件化之 DynamicLoadApk 原理解析
背景:
插件化技術主要是解決apk體積、內存、cpu占用逐漸增大問題,實現熱插拔(即在不發版的情況下更新app的功能)。
通過插件化還可以實現模塊之間解耦,并行開發,提高apk編譯速度。
什么是插件化:
ANDROID插件化是指將整個APP按照模塊拆分,每個模塊以插件的形式組裝成一個APP。要實現插件化必需要理解另
外一個概念—組件化。組件是指工程內通用性和復用行較高的模塊以及相對獨立的功能模塊。比如,網絡框架、圖片
緩存、PASSPORT等都可以作為一個組件集成到工程內,從而實現公共模塊的復用以及模塊之間的解耦。
組件化是插件化的前提,只有實現了工程結構的組件化才能實現插件化,從而可以實現模塊以插件的形式集成到工程中,
也可以實現模塊動態更新修復bug或者發布小版本。
插件化的優缺點:
優點:
1.模塊解耦,模塊之間耦合度降低,提高代碼的復用度。
2.解決單個dex方法數65535的限制。
3.動態升級,修復bug或者小版本升級不需要發版,對于部分新功能可以解除版本之間的限制。
4.并行開發(提高編譯、開發速度)
5.主app的體積減小,部分插件在需要的時候動態下載。
缺點:
1.大部分插件化方案是通過hook底層方法實現,存在機型兼容性問題。
2.目前插件化技術方案不完善導致在生產環境下會遇到各種坑。
DynamicLoadApk原理解析:
在詳細講解DynamicLoadApk之前先了解一下插件化中比較重要的兩個概念:宿主、插件。
宿主:指主app,可以稱之為host,宿主可以加載插件,是整個app的入口。
插件:插件app,被宿主加載的app,可以跟普通app一樣被安裝單獨運行。
插件化宿主和插件的組織關系: 通過上圖我們可以看到宿主和插件的關系,插件依賴于宿主,宿主可以加載多個插件。
宿主可以調用插件但插件不可以調用宿主。
插件化宿主和插件的組織關系:
image2016-10-2712-52-8.png
通過上圖我們可以看到宿主和插件的關系,插件依賴于宿主,宿主可以加載多個插件。宿主可以調用插件但插件不可以調用宿主。
框架設計:
image2016-10-2712-52-31.png
整體的框架主要包括四個部分:
DLPluginManager:插件管理模塊,負責插件的加載、管理以及啟動、解綁插件組件。下圖是DLPluginManager加載插件的流程:
image2016-10-2712-52-42.png
image2016-10-2712-52-51.png
Proxy:代理組件模塊,目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。
Proxy Impl代理組件公用邏輯模塊,與(2)中的 Proxy 不同的是,這部分并不是一個組件,而是負責構建、加載插件組件的管理器。這些 Proxy Impl
通過反射得到插件組件,然后將插件與 Proxy 組件建立關聯,最后調用插件組件的 onCreate 函數進行啟動。
Base Plugin插件組件的基類模塊,目前包括 DLBasePluginActivity(插件 Activity 的基類)、DLBasePluginFragmentActivity(插件 FragmentActivity
的基類)、DLBasePluginService(插件 Service 的基類)。
宿主調用插件的流程:
image2016-10-2712-53-9.png
上面是調用插件 Activity 的流程圖,其他組件調用流程類似。
(1) 首先通過 DLPluginManager 的 loadApk 函數加載插件,這步每個插件只需調用一次。
(2) 通過 DLPluginManager 的 startPluginActivity 函數啟動代理 Activity。
(3) 代理 Activity 啟動過程中構建、啟動插件 Activity。
總結:
以上是DynamicLoadApk的整體框架和實現原理,該框架hook底層代碼比較少使用代理模式實現插件中Android四大組件的使用,相比其它框架系統兼容性問題比較少。
來自:http://www.jianshu.com/p/7c6fbe468c00