前言:前一段时间新开源了一种全面插件化的方案-- RePlugin,之前一种都在关注 DroidPlugin 并且很早也在项目中试用了,但最终没有投入到真正的生产环节,一方面是项目中没有特别需要插件化的需求,另一方面也考虑到 DroidPlugin 不是特别稳定,Android系统每更新一次 DroidPlugin 可能就会出现一些 Bug,毕竟 Hook 了 Android 原生的太多东西,系统一旦更新引发 Bug 是在所难免的。当然,这些并不能否认 DroidPlugin 的优秀,它的原理和思路值得我们深入探究、学习,前一段时间更新过几篇插件化的原理分析的文章(基于 DrodiPlugin 原理)学习过程中不得不叹服作者的思路和技术深度!前几篇小白也能看懂的插件化系列文章仍然会不定期更新,但目前我们可以先来学习学习 RePlugin,毕竟多学无害,也能互相参考他们的思路,比较优缺点。
RePlugin 是一套完整的、稳定的、适合全面使用的、占坑类插件化方案:
完整的:让插件运行起来“像单品那样”,支持大部分特性。
稳定的:官方宣称,其框架奔溃率“万分之一”。
适合全面使用的:其目的是让应用内的“所有功能皆为插件”。
占坑类:以稳定为前提的 Manifest 占坑思路。
插件化方案:基于 Android 原生 API 和语言来开发,充分利用原生特性。
(以上定义引自官方wiki)
以上代码有三点需要注意:
需要将 apply plugin: 'replugin-host-gradle' 放在 android {...} 之后。
如果项目需要支持 AppComat,则需要将 repluginHostConfig 的 userAppCompat 置为 true。
如果应用需要个性化配置坑位数量,则需要在 repluginHostConfig 中添加以下代码进行配置:
当然,同时不要忘了在 AndroidManifest 对 MyApplication 的相关配置。
说明:有时候由于项目原有结构的需要,我们可能不能直接使用继承 RePluginApplication 的方式,这个问题看来 RePlugin 开发者也想到了,所以还特地多了一种选择,下面是项目的 Application 不继承 RePluginApplication 的方式:
新建一个工程做为插件APP,这里为了方便起见,直接在主工程中新建了一个 Module。
RePlugin 对插件定义两种方式一种是外置插件、一种是内置插件。
外置插件:即从网络下载或者从SD卡中获得的,以 .apk 结尾。
内置插件:内置于 APP 之中,并随 APP 一并发版,需要将插件 apk 改成 .jar 结尾放入主程序的assets/plugins目录。
安装插件:
同时别忘了添加文件读写的权限。 输出日下:
安装成功了! (升级插件也是用 install() 方法,不可降级,同本版可覆盖安装)
启动插件
先来看一下 RePlugin.java 中启动插件相关的源码:
根据 RePlugin 的 startActivity() 和 createIntent() 方法注释中的示例可知,启动插件需要先用插件的名字和目标Activity的全路径创建一个 Intent,然后调用 RePlugin.startActviity() 启动即可:
点击按钮,输出如下:
启动失败了!(插件名称确实是:Plugin1,而不是 plugin1 )
把 ==createIntent() 方法的第一参数换成插件的包名 cn.codingblock.plugin1 ==试一试,居然可以了。
但是,注释总不会这样赤裸裸的坑我们吧!
卸载插件
点击卸载,输入如下:
没卸载成功?哈哈,这个简单,原套路把参数换成包名,果然可以了:
启动插件那里毕竟在官方教程里面找不到,但是 Plugin.uninstall() 方法传入插件名即可这可是官方文档说的,这次不会是官方文档和源码注释合起伙来坑我们把? 经过多次试验后,有个有趣的发现:对于启动插件创建 Intent 的createIntent() 方法和 卸载插件的 RePlugin.uninstall() 方法,如果项目是使用继承 RePluginApplication 方式的话,参数传包名才生效;如果不是继承的方式传插件名才生效!(本人是在一款小米3手机上试验的,由于并没有广泛测试,所以不保证其他手机也是这个套路)这真是奇了葩了!
卸载插件时有一点需要注意:如果插件正在运行,则不会立即卸载插件,而是将卸载诉求记录下来。直到所有“正在使用插件”的进程结束并重启后才会生效。(引自官方说明)
添加内置插件非常简单,首先在主工程的 assets 目录下创建一个 plugins 文件夹,然后将要作为插件的 apk 后缀名改成 .jar 并放入到新建的 plugins 文件夹下,剩下的事情就不用管了,交给 RePlugin 即可,也就说,框架会自动加载插件。
内置插件无需开发者安装,启动方式和外置插件一致,但不可删除。
内置插件可通过 RePlugin.install() 升级(需要先将升级包下载好),升级后等同于外置插件。
初步体验了一下发现,虽然目前有可能会有那么一点坑需要踩一踩,在使用起来也不比 DroidPlugin 方便,需要在宿主和插件两端都要做集成工作。但总体明显发现,这次的插件化框架明显比以前那些的插件化框架资料更加的全面、丰富,而且从 wiki 上发现 RePlugin 团队充满了很大的热情在孜孜不倦维护、更新,并且计划明确,哪些功能在未来会添加、哪些功能在未来会被舍弃,一目了然,让我们更加看到了 RePlugin 美好的未来,我相信在未来的插件化领域即使 RePlugin 不能一家独大,也必然处于一个非常重要的地位!