VirtualApk插件

VirtualApk介紹

VirtualAPK是滴滴出行自研的一款插件化框架。
??傳送門

VirtualApk

接入文檔

接入步驟以及細(xì)節(jié)可參考文檔

VirtualAPK 框架接入指南

VirtualAPK 插件開發(fā)指南

接入注意點(diǎn)

  • gradle 版本可以使用3.0.0 ,官網(wǎng)建議是2.14.1 實(shí)際demo運(yùn)行可行
  • 插件模塊配置信息virtualApk,放在文件末尾(注意個(gè)配置的含義)
 virtualApk {
    packageId = 0x6f             // 插件資源id,避免資源id沖突
    targetHost='../host/app'     // 宿主工程的路徑(絕對或者相對路徑)
    applyHostMapping = true      // 插件編譯時(shí)是否啟用應(yīng)用宿主的apply mapping
}
  • 打包插件之前需要先編譯宿主工程,編譯之后生成一些信息(在build/VAHost文件夾下),插件構(gòu)建的時(shí)候會(huì)讀取這些信息,所以要確保運(yùn)行的宿主和插件基于相同信息構(gòu)建的,宿主變化時(shí)請重新構(gòu)建插件
  • 插件運(yùn)行(不能直接Run出來)需要通過 命令打出
    • ./gradlew clean assemblePlugin

原理簡介

插件化重點(diǎn)看下類的加載以及資源的加載:

類的加載VirtualAPK大體方案如下:

  • Activity:在宿主apk中提前占幾個(gè)坑,然后通過“欺上瞞下”(這個(gè)詞好像是360之前的ppt中提到)的方式,啟動(dòng)插件apk的Activity;因?yàn)橐С植煌膌aunchMode以及一些特殊的屬性,需要占多個(gè)坑。

  • Service:通過代理Service的方式去分發(fā);主進(jìn)程和其他進(jìn)程,VirtualAPK使用了兩個(gè)代理Service。

  • BroadcastReceiver:靜態(tài)轉(zhuǎn)動(dòng)態(tài)

  • ContentProvider:通過一個(gè)代理Provider進(jìn)行分發(fā)。

資源的加載:

主要是在LoadedOlugin中的createResources方法中

private static Resources createResources(Context context, File apk) {
        if (Constants.COMBINE_RESOURCES) {
            Resources resources = ResourcesManager.createResources(context, apk.getAbsolutePath());
            ResourcesManager.hookResources(context, resources);
            return resources;
        } else {
            Resources hostResources = context.getResources();
            AssetManager assetManager = createAssetManager(context, apk);
            return new Resources(assetManager, hostResources.getDisplayMetrics(), hostResources.getConfiguration());
        }
    }

Constants.COMBINE_RESOURCES

  • 為true的時(shí)候
    • ResourcesManager.createResources通過反射將當(dāng)前apk的路徑添加到host中
    • 將apk的class加載到了主host中
    • 插件可以引用到主項(xiàng)目中的資源
  • 為falsede 時(shí)候
    • 重新創(chuàng)建了新的resource
    • 插件和主項(xiàng)目資源分離,不可引用

VirtualAPK四大組件源碼分析

VirtualAPK 資源加載機(jī)制分析

插件和宿主之間的通信

插件如何和宿主交互?
通過compile相同aar的方式來交互。 比如,宿主工程中compile了如下aar:

compile 'com.didi.foundation:sdk:1.2.0'
compile 'com.didi.virtualapk:core:[newest version]'
compile 'com.android.support:appcompat-v7:22.2.0'
但是插件工程需要訪問宿主sdk中的類和資源,那么可以在插件工程中同樣compile sdk的aar,如下:

compile 'com.didi.foundation:sdk:1.2.0'
這樣一來,插件工程就可以正常地引用sdk了。并且,插件構(gòu)建的時(shí)候會(huì)自動(dòng)將這個(gè)aar從apk中剔除。

上述就是VirtualAPK中插件和宿主通信的基本方式。

拿龍珠項(xiàng)目舉個(gè)例子??

龍珠項(xiàng)目目前各個(gè)模塊之間的跳轉(zhuǎn)是通過路由來實(shí)現(xiàn),在VirtualApk插件中使用路由,只需要在主App中和插件中都引入路由,做好各自相應(yīng)的注冊,就能正常跳轉(zhuǎn)。

Virtual不支持

  1. 目前暫不支持的特性
    暫不支持Activity的一些不常用特性(比如process、configChanges等屬性),但是支持theme、launchMode和screenOrientation屬性;
  2. overridePendingTransition(int enterAnim, int exitAnim)這種形式的轉(zhuǎn)場動(dòng)畫,動(dòng)畫資源不能使用插件的(可以使用宿主或系統(tǒng)的);
  3. 插件中彈通知,需要統(tǒng)一處理,走宿主的邏輯,通知中的資源文件不能使用插件的(可以使用宿主或系統(tǒng)的)。
  4. 插件的Activity中不支持動(dòng)態(tài)申請權(quán)限。

結(jié)論

由于以下幾種問題,Virtual插件方案和當(dāng)前項(xiàng)目適用性不好,所以不使用:

  1. 可能是由于第一個(gè)不支持,在房間收到切換橫豎屏無效,具體原因未明。
  2. 主hostApp和插件之間必須有一個(gè)明確的路徑
virtualApk{
    targetHost='../host/app'     // 宿主工程的路徑(絕對或者相對路徑)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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