Android插件化RePlugin探索

插件化與組件化的區(qū)別

組件化,也稱模塊化,主要通過拆分單獨(dú)功能模塊及通用模塊來實(shí)現(xiàn)較大應(yīng)用的松耦合。把需要獨(dú)立拆分的業(yè)務(wù)設(shè)計(jì)成一個(gè)模塊,各個(gè)模塊的代碼最終打包成一個(gè)對(duì)應(yīng)的aar,主App和業(yè)務(wù)App設(shè)計(jì)成一個(gè)運(yùn)行殼子,編譯打包時(shí)候使用Gradle做maven依賴即可。

arr是針對(duì)Android Library而言的,是IDE針對(duì)Android Library的打包。本身是zip格式的文件。

插件化:某個(gè)業(yè)務(wù)模塊單獨(dú)做出一個(gè)Apk,主App直接使用插件的方式,如果需要某種功能,那么直接加載某一個(gè)apk,而不是直接依賴代碼的形式。

插件化方案

Fragement加載方案:參考項(xiàng)目AndroidDynamicLoader,云音樂采用類似方案。

Activity代理方案:與Fragment加載原理類似,仍然使用本地代理容器Activity打開頁面,由代理容器對(duì)原Activity生命周期進(jìn)行托管。

Activity占坑方案:采用Hook技術(shù),可動(dòng)態(tài)注冊(cè)和加載Acitivity,可實(shí)現(xiàn)一對(duì)多

此處的Hook是指通過Java反射手段,獲取并修改與系統(tǒng)Server等交互的Internal API來讓框架正常工作的行為。

技術(shù)選型

  • 目前成熟且活躍的方案
    360的RePlugin、淘寶的atlas、滴滴的VirtualAPK、非商業(yè)組織的Small。
    讓模塊最終具備動(dòng)態(tài)性是它們最核心的能力。
  • 主要考慮因素
    穩(wěn)定(不崩潰);
    高可用(具備可插拔/安全校驗(yàn)/內(nèi)外置插件等成熟框架所具備的功能);
    可維護(hù)(在前后向兼容時(shí)能提供新老版本對(duì)最新開發(fā)的插件的支持)。參考

RePlugin介紹

介紹
RePlugin是一套適合全面使用的占坑類插件化方案,目標(biāo)是全面插件化。
內(nèi)置插件主要應(yīng)用于基礎(chǔ)重要模塊,外置插件可動(dòng)態(tài)添加,并實(shí)現(xiàn)插件既可獨(dú)立apk存在,也可通過宿主啟動(dòng)。

在實(shí)際中存在小Bug,將外置插件以獨(dú)立apk形式安裝后,宿主第一次啟動(dòng)該插件會(huì)失敗,重啟會(huì)正常啟動(dòng)。

架構(gòu)
系統(tǒng)層——Android:為Android Framework層。只有ClassLoader是Hook的,而AMS、Resources等都沒有做Hook,確保了其穩(wěn)定性。
框架層——RePlugin框架:RePlugin框架層,只有RePlugin是對(duì)“上層完全公開”的,其余均為Internal,或“動(dòng)態(tài)編譯方案”生效后的調(diào)用,對(duì)開發(fā)者而言是“無需關(guān)心”的。
插件層——各類業(yè)務(wù)插件及基礎(chǔ)插件。具體可分為內(nèi)置插件和外置插件。

唯一Hook點(diǎn):ClassLoader

  • Java中的ClassLoader:
    BootClassLoader是系統(tǒng)啟動(dòng)時(shí)創(chuàng)建的。
    PathClassLoader是應(yīng)用啟動(dòng)時(shí)創(chuàng)建的,只能加載內(nèi)部dex。
    DexClassLoader可以加載外部dex。

  • RePlugin中存在兩個(gè)主要ClassLoaer:
    1、RePluginClassLoader: 宿主App中的Loader,繼承PathClassLoader,也是唯一Hook住系統(tǒng)的Loader。
    2、PluginDexClassLoader: 加載插件的Loader,繼承DexClassLoader。用來做一些“更高級(jí)”的特性。

四大組件實(shí)現(xiàn)插件化的實(shí)現(xiàn)原理

  • Activity 在啟動(dòng)的時(shí)候替換成了合適的占坑的activity , 然后ClassLoader loadClass 的時(shí)候根據(jù)占坑Activity 到真正Activity 的映射關(guān)系,
    輸入占坑Activity,返回真正Activity 的類,避免了需要hook.
  • BroadcastReceiver 是把所有靜態(tài)注冊(cè)都動(dòng)態(tài)注冊(cè)在一個(gè)代理Receiver, 收到廣播在代理Receiver 進(jìn)行分發(fā).
  • Service 實(shí)現(xiàn)邏輯是這里其實(shí)是直接在UI線程調(diào)用了service 的相關(guān)生命周期的方法.同時(shí)啟動(dòng)一個(gè)service來提高service所在進(jìn)程優(yōu)先級(jí).
  • ContentProvider 這里使用的是代理ccontentprovide,在對(duì)應(yīng)的生命周期使用反射將對(duì)應(yīng)類生成出來. 然后調(diào)用對(duì)應(yīng)的聲明周期方法.
    參考

Activity啟動(dòng)的主要流程

  1. 通過代理類PluginLibraryInternalProxy對(duì)Activity進(jìn)行啟動(dòng)。
  2. 加載插件,找到目標(biāo)啟動(dòng)的activity的ActivityInfo信息。
  3. 搜索匹配容器,為要啟動(dòng)的目標(biāo)Activity的分配坑位。將占坑信息與目前Activity建立映射關(guān)系。
    分配坑位的優(yōu)先級(jí)是先找上一個(gè)活的->沒有則找空白的->重用沒引用的最老的
  4. 將Activity信息存入坑位,啟動(dòng)坑位Activity。
  5. 使用RePluginClassLoader進(jìn)行l(wèi)oadClass
  6. 根據(jù)坑位找到目標(biāo)activity所在插件,由插件的PluginDexClassLoader去加載activity
  7. PluginDexClassLoader遵循雙親委派模型流程,仍然沒有找到則從宿主ClassLoader中加載(宿主啟動(dòng)插件activity一般不會(huì)走到這一步)。

動(dòng)態(tài)編譯方案
RePlugig動(dòng)態(tài)編譯方案會(huì)將Activity替換成PluginActivity,使用代理模式進(jìn)行檢查操作確認(rèn)后啟動(dòng)相應(yīng)Activity。具體替換規(guī)則如下:

/* LoaderActivity 替換規(guī)則 */
def private static loaderActivityRules = [
        'android.app.Activity'                    : 'com.qihoo360.replugin.loader.a.PluginActivity',
        'android.app.TabActivity'                 : 'com.qihoo360.replugin.loader.a.PluginTabActivity',
        'android.app.ListActivity'                : 'com.qihoo360.replugin.loader.a.PluginListActivity',
        'android.app.ActivityGroup'               : 'com.qihoo360.replugin.loader.a.PluginActivityGroup',
        'android.support.v4.app.FragmentActivity' : 'com.qihoo360.replugin.loader.a.PluginFragmentActivity',
        'android.support.v7.app.AppCompatActivity': 'com.qihoo360.replugin.loader.a.PluginAppCompatActivity',
        'android.preference.PreferenceActivity'   : 'com.qihoo360.replugin.loader.a.PluginPreferenceActivity',
        'android.app.ExpandableListActivity'      : 'com.qihoo360.replugin.loader.a.PluginExpandableListActivity'
]

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 是時(shí)候來一波Android插件化了 是時(shí)候來一波Android插件化了前言Android開發(fā)演進(jìn)模塊化介紹插件化介...
    流水不腐小夏閱讀 4,932評(píng)論 3 51
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,276評(píng)論 25 708
  • RePlugin,360開源的全面插件化框架,按照官網(wǎng)說的,其目的是“盡可能多的讓模塊變成插件”,并在很穩(wěn)定的前提...
    戀貓?jiān)铝?/span>閱讀 33,908評(píng)論 29 122
  • 題記 寫這篇關(guān)于Replugin插件化框架的分析,旨在引導(dǎo)讀者去快速的了解RePlugin的大概實(shí)現(xiàn)原理,文中會(huì)拋...
    Ihesong閱讀 1,988評(píng)論 0 1
  • 私人情書 一款專門針對(duì)頑固體質(zhì)和想瘦身的小仙女的產(chǎn)品 (??ω?)關(guān)于情書的瘦身原理:它的瘦身原理...
    kosf7cl閱讀 1,823評(píng)論 2 2

友情鏈接更多精彩內(nèi)容