新建项目 DlPluginHost,下载dynamic-load-apk源码app
1.将dynamic-load-apk 文件夹中的lib作为module导入到DlPlginHostide
2.导入到PluginHost后,PluginHost引用lib,项目文件目录以下:gradle
3.新建插件项目DlPluginFirst,将dynamic-load-apk下的lib模块编译生成的jar,丢到插件的libs目录下: ui
修改插件的 gradle 文件:spa
注意这里用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,悬浮球。
本章代码: