1. 程式人生 > >dynamic-load-apk 插件與宿主方法互調

dynamic-load-apk 插件與宿主方法互調

-a rstp com 不一致 host width blog clas 技術分享

新建項目 DlPluginHost,下載dynamic-load-apk源碼

1.將dynamic-load-apk 文件夾中的lib做為module導入到DlPlginHost

技術分享

2.導入到PluginHost後,PluginHost引用lib,項目文件目錄如下:

技術分享

3.新建插件項目DlPluginFirst,將dynamic-load-apk下的lib模塊編譯生成的jar,丟到插件的libs目錄下:

技術分享

修改插件的 gradle 文件:

技術分享

註意這裏用provided只是為了讓插件通過編譯,最終打包出來的插件是不會包含這個lib的,因為宿主中已經包含了這個lib,如果用 compile去包含,雖然可能同樣可以達到效果,但是插件包莫名增加了一個lib的大小,沒必要

4.這樣宿主跟插件都有了,宿主app是根據demo做的,所有我們把 DlPluginFirst build生成apk,放在根目錄的 DynamicLoadHost目錄下:

技術分享

5.啟動宿主app(DlPluginHost),點擊Item,就可以正常拉起 插件app(DlPluginFirst)了:

技術分享

下面我們開始處理插件與宿主間的方法互調:

1.我們先看一下dynamic-load-apk的源碼(以下簡稱DL):

技術分享

註意紅色箭頭部分:

很明顯這裏獲取到插件的 classname ,然後通過loadPluginClass 獲取該類的實例,loadPluginClass代碼如下:

技術分享

1.這裏可以拿到類的實例的話,那麽接下來的問題就好處理了,很多人想到的第一個處理方法就是,通過反射出該類的方法然後直接進行調用,but,這樣實驗下來是有問題的 ,method 是可以反射出來的,但是調用的時候 報錯:class 不一致,這個方法pass.

那怎麽解決這個問題呢,我們可以這麽做,我們做一個host與plugin共同引用的interface,然後通過interface來達到調用的效果:

1.在 host中新建module plugininterface , 並添加接口類:

技術分享

由於反射出插件類是在 dl-lib中實現的 ,所以lib添加依賴 plugininterface, 再把plugininterface生成jar 拷貝到 plugin的libs 中

技術分享

由於後面還需要做插件調用宿主方法的jar,這邊我們將這個class修改名字 區分一下:

技術分享

由於host中包含這個 module 所以放在libs下 同樣用 provided 引用,防止重復。

接下來就是考慮怎麽調用的問題了,我們可以這麽做,在DL的 DlPluginManager中增加一下方法:

技術分享

將plugin類反射出來,由於plugin類是繼承 plugininterface 接口的,所以通過反射出來的 PluginInterface,中的接口是可以調用到插件的方法的!!!

plugin的代碼如下:

技術分享

技術分享

由於dl是通過代理實現的 所有plugin中activity其實都是host中代理的activity,所以通過上面的方法實施獲取插件版本號是獲取不到的 ,因為代理的問題,獲取的context總是host的,獲取出來的版本號其實是host的版本號。

反射出來之後,我們通過host 開始調用插件的方法(這個方法直接反射plugin的方法,不走plugin activity中生命周期):

技術分享

最後查看log日誌,的確是可以調用到的:

技術分享

宿主調用插件的方法,到此就結束了,想想插件怎麽調用宿主的方法呢,其實套路是一樣的,我們在host中新建一個 hostinterface module,

技術分享

註意hostinterface 提供給plugin 調用的包名,類名以及方法名都要一直,這樣plugin才能調用到host的 HostMethod., hostinterface 中的方法只是 host中方法的空殼,只是為了讓plugin能找到host的具體實現方法:

技術分享

具體實現還是在host中:

技術分享

同樣我們把 hostinterface 的jar包拷貝出來丟到plugin中,修改jar包名稱以作區分 :

技術分享

接下來DlPluginFist編譯成jar,丟到根目錄DynamicLoadHost中,啟動host拉起 plugin:

技術分享

invokeHostMethod 對應的代碼如下:

技術分享

執行結果,查看log,調用成功:

技術分享

這樣host, plugin的互調就到這裏結束了,下一章將 通過 dynamic-load-apk實現 host 顯示插件懸浮窗,類似九遊遊戲sdk,懸浮球。

本章代碼:

DlPluginHost.zip

DlFirstPlugin.zip

dynamic-load-apk 插件與宿主方法互調