Android 插件化開發(四):插件化實現方案


在經過上面鋪墊后,我們可以嘗試整體實現一下插件化了。這里我們先介紹一下最簡單的實現插件化的方案。

一、最簡單的插件化實現方案

最簡單的插件化實現方案,對四大組件都是適用的,技術面涉及如下:

1). 合並所有插件的Dex,來解決插件的類的加載問題。

2). 預先在宿主的AndroidManifest.xml文件中聲明插件的四大組件。(如果插件組件過多會很麻煩)

3). 把插件中的所有資源一次性的合並到宿主的資源中。(合並時可能會導致id沖突)

使用此組件化方案實現時,Service、ContentProvider 和 Receiver 只要合並 dex 就夠了,因為這些沒有資源訪問的概念。

但是Activity插件化實現時就會比較麻煩,因為Activity嚴重依賴資源,想實現Activity的插件化就必須解決加載插件中資源的問題。

在 Android 插件化開發(三):資源插件化 中我們介紹過AssetsManager和Resource這兩個類的關系,AssetManager有一個addAssetPath方法,可以一次性把插件的路徑都導入,然后再生成一個含有全局資源的Resource,以后無論查找插件還是宿主的的資源都能找到了。

雖然此方案能實現插件化,但是此方案有很大的問題:

1. 插件的四大組件要事先聲明,無法動態新增,這樣對於Activity來說是無法兼容的問題(其他組件相對問題較少)。

2. 資源id會沖突。

3. 無法預料插件內Activity,對於插件內動態新增的Activity無法進行使用。

項目代碼倉庫地址:https://github.com/renhui/RHPluginProgramming/tree/master/ZeusStudy

了解如何實現一個最簡單的插件化之后,我們再整理一下Activity如何實現插件化。這里單獨再提一下 Activity 是因為 Activity 是 App 中使用頻率最高的組件,所以這里我們先講述一下Activity的插件化。

Activity 的插件化需要解決3方面的技術問題:

1). 宿主App可以加載App中的類。

2). 宿主App可以加載App中的資源。

3). 宿主App可以加載插件中的Activity。

前兩個技術問題,我們已解決了,這里我們講一下第3個的技術問題的解決方案。主要的解決方案有很多種,這里只簡單以兩個有標志性的框架:

a. 以DroidPlugin框架為代表的動態替換方案,提供對Android底層的各類進行Hook,以達到插件化中的四大組件的目的。

b. 以DynamicLoadApk框架為代表的靜態代理方案,通過ProxyActivity統一加載插件中的所有Activity。

 

下面我們再講一下DynamicLoadApk框架,此框架在《Android插件化開發指南》書中重點提及了,本人也比較感興趣。

三、DynamicLoadApk 插件化框架

DynamicLoadApk 是一個開源的 Android 插件化框架。

插件化的優點包括:(1) 模塊解耦,(2) 動態升級,(3) 高效並行開發(編譯速度更快) (4) 按需加載,內存占用更低等等。

DynamicLoadApk 提供了 3 種開發方式,讓開發者在無需理解其工作原理的情況下快速的集成插件化功能。

  1. 宿主程序與插件完全獨立;
  2. 宿主程序開放部分接口供插件與之通信;
  3. 宿主程序耦合插件的部分業務邏輯。

1. DynamicLoadApk 框架核心概念

(1) 宿主:主 App,可以加載插件,也稱 Host。

(2) 插件:插件 App,被宿主加載的 App,也稱 Plugin,可以是跟普通 App 一樣的 Apk 文件。

(3) 組件:指 Android 中的Activity、Service、BroadcastReceiver、ContentProvider,目前 DL 支持Activity、Service以及動態的BroadcastReceiver。

(4) 插件組件:插件中的組件。

(5) 代理組件:在宿主的 Manifest 中注冊,啟動插件組件時首先被啟動的組件。目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。

(6) Base 組件:插件組件的基類,目前包括 DLBasePluginActivity(插件 Activity 的基類)、DLBasePluginFragmentActivity(插件 FragmentActivity 的基類)、DLBasePluginService(插件 Service 的基類)。

DynamicLoadApk 原理的核心思想可以總結為兩個字:代理。通過在 Manifest 中注冊代理組件,當啟動插件組件時首先啟動一個代理組件,然后通過這個代理組件來構建、啟動插件組件。

2. DynamicLoadApk 框架設計思路

上面是 DynamicLoadApk 的總體設計圖,DynamicLoadApk 主要分為四大模塊:

(1) DLPluginManager

插件管理模塊,負責插件的加載、管理以及啟動插件組件。

(2) Proxy

代理組件模塊,目前包括 DLProxyActivity(代理 Activity)、DLProxyFragmentActivity(代理 FragmentActivity)、DLProxyService(代理 Service)。

(3) Proxy Impl

代理組件公用邏輯模塊,與(2)中的 Proxy 不同的是,這部分並不是一個組件,而是負責構建、加載插件組件的管理器。這些 Proxy Impl 通過反射得到插件組件,然后將插件與 Proxy 組件建立關聯,最后調用插件組件的 onCreate 函數進行啟動。

(4) Base Plugin

插件組件的基類模塊,目前包括 DLBasePluginActivity(插件 Activity 的基類)、DLBasePluginFragmentActivity(插件 FragmentActivity 的基類)、DLBasePluginService(插件 Service 的基類)。

3. DynamicLoadApk 流程說明

上面是調用插件 Activity 的流程圖,其他組件調用流程類似。

(1) 首先通過 DLPluginManager 的 loadApk 函數加載插件,這步每個插件只需調用一次。

(2) 通過 DLPluginManager 的 startPluginActivity 函數啟動代理 Activity。

(3) 代理 Activity 啟動過程中構建、啟動插件 Activity。

四、其他的插件化解決方案

在介紹其他的插件化解決方案之前,我們先看一下插件化技術的演進圖:

 以下是相關的項目地址:

7) Small:https://github.com/wequick/Small

 

雖然插件化的相關框架不少,但是核心技術還是不變的,那就是:反射 + 代理

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM