-
Notifications
You must be signed in to change notification settings - Fork 1.5k
插件的信息
本文主要讲述如何获取并使用插件的一些信息。这些信息大致包括:
RePlugin的插件可以有两种名字,分别是:插件包名、插件别名。
- 插件包名:顾名思义,就是插件的PackageName
- 插件别名:为了“精简包名”而设计的别名,也是RePlugin推荐大家使用的
值得注意的是,在您调用插件逻辑时,您既可以使用插件包名,也可以使用插件别名,两者可以混用而不受影响(在RePlugin 2.2.0中支持)
插件包名可以任意起名,不受限制。
注意,若您的APK既作为单品,又作为插件,则建议分成两个包名,且Provider的Authority也建议改名,这样可针对不同的场景(插件还是单品)来做不同的处理。
除了插件包名外,针对很多开发者的诉求(包名太长、有可能会改等),我们提出了“插件别名”的概念。
插件别名应做到尽可能的简短、易懂,并尽量为全小写。如:webview、push、protobuf等
要声明插件别名,需要在插件的AndroidManifest.xml中声明以下Meta-data:
<meta-data
android:name="com.qihoo360.plugin.name"
android:value="[你的插件别名]" />
针对内置插件而言:
- 若不填写插件别名,则RePlugin会将内置插件的“文件名”作为其插件名
- 其优先级为:Meta-data声明的 > 文件名
而针对外置插件而言:
- 若不填写插件别名,则RePlugin只能允许使用“插件包名”
- P-n类型插件在生成“文件头”时就必须要设置别名,故不受影响
以下为360手机卫士或其它合作App采用的设计,可供您参考:
- 建议给主要的、经常用到的插件,声明其“插件别名”(虽然不硬性要求),这样代码会更加简洁。
试想一下,是每次用“com.qihoo360.mobilesafe.plugin.webview”好呢?还是“webview”好呢?
- 一些外部合作的插件(如360桌面等)可以只使用插件包名
RePlugin用到的版本可分为三种:插件版本号、“插件协议版本号”和“插件框架版本号”。
插件版本号是很容易理解的,就是插件的VersionCode,可以自由发挥(当然了,毕竟是Integer类型,所以别超过32位最大值)。
插件的VersionName因其类型为String,故不作为我们的“插件版本”
为了更好的维护插件的版本,以360手机卫士的经验来看,建议可由“三位数”组成。
其中,第一位是大版本,第二位是功能版本,第三位是修复版本。
例如——101。其中第一位“1”为大版本,第二位“0”为功能版本,第三位“1”是修复版本
- 大版本:当插件发生“极其重要的变化”时,可调整此版本
- 功能版本:当插件增加了多个新功能,或优化了多个功能项时,可调整此版本
- 修复版本:当插件出现一些Bug需要修复,或一些很小的改动项,或做A/B Test时,可调整此版本
这样做的好处是显而易见的——各插件能做到“并行开发”,而不受其影响。当然,五位数、七位数都可以,可根据您们的业务需要来定。
为了让插件和主程序、插件和插件之间,在针对“巨大接口调整”后仍能确保没有问题,故设立了“插件协议版本号”。
绝大多数开发者可无需关注此版本号,目前设定的默认值是“10”。
我们为什么要设立这个呢?
在开发应用的过程中,难免会遇到一种情况:插件之间,插件与宿主间的交互相对比较频繁。
如果某个插件或主程序的接口发生了极其重大的变化(例如彻底的重构和删除),首先面临的一个问题是——旧插件将无法再使用,其次还要考虑到新插件要做“各种兼容”,例如“逐一判断”接口等,非常费时费力。
为此,我们引入了“插件协议版本号”的概念。
要声明插件协议版本号,您需要在插件的AndroidManifest.xml中声明以下Meta-data:
<meta-data
android:name="com.qihoo360.plugin.version.low"
android:value="[你的插件协议版本号]" />
<meta-data
android:name="com.qihoo360.plugin.version.high"
android:value="[你的插件协议版本号]" />
目前要求low和high应保持相等。
为什么会有low和high,而不是一个api_ver就搞定?
这个和我们之前RePlugin在2014年的更复杂的情形有关,时间关系不在此赘述。然而,随着目前框架的逐渐成熟,这个low和high其实完全可以“合二为一”(内部也是这么用的)。在未来版本,我们将做重构,确保只保留一个。
为了让插件兼容主程序的RePlugin框架,故设立了“插件框架版本号”。截止到2017年6月底,最新的版本号为“4”。
我们为什么要设立这个呢?
从2013年开始,RePlugin经历了数次非常大的改进,尤其以2017年的为甚。而仅以360手机卫士为例,截止到2017年6月底,我们已有102个插件,而有些插件仍需运行在早期的手机卫士上(例如杀毒、清理等),即便还在持续的更新。
若我们不设立这个版本号,则直接导致的结果是:旧插件在新、老手机卫士(或RePlugin架构)上的行为变得不可预测。
举个例子:有个插件是跑在早期手机卫士框架上,彼时还不支持“完全自定义Theme”方案。出于习惯,某Activity设置了一个特殊的,甚至是不正确的Theme。由于早期版本不生效,所以还一直相安无事。然而,如果没有“框架版本号”,则一旦框架突然支持了自定义Theme,则那个“有问题的”Theme就突然生效,导致行为不可预期的问题。
要声明插件框架版本号(绝大多数情况下不需要,默认为4),您需要在插件的AndroidManifest.xml中声明以下Meta-data:
<meta-data
android:name="com.qihoo360.framework.ver"
android:value="[你的框架版本号]" />
插件信息的类是 PluginInfo,无论是宿主还是插件均可使用。而要获取插件信息还是非常简单的:
- 调用 RePlugin.getPlugin() 方法,可获取任意插件的信息,也可以借此判断插件是否安装(若为null则表示没有安装)
- 调用 RePlugin.getPluginInfoList() 方法可获取所有已安装(包括内置插件)的信息
- 调用 RePlugin.install() 方法,其返回值是“安装成功后”的PluginInfo。若返回Null则表示“安装失败”
PluginInfo中有一个“神奇的”方法:getPendingUpdate,很多人对此方法有一定的疑惑。然而一旦您遇到这种情况,就会发现这个方法变得非常有必要了。例如:
当前正在运行“卫士体检”插件,后在进程没有重启的情况下,对此插件作了升级。而我想获取这两个信息:
- 当前正在运行的插件信息
- 新版本(只不过还没生效)的插件信息
以上两种情况都会遇到,应该怎么办?
我们的做法是:
- 当时调用了 RePlugin.install() 方法,其返回值就是“新版本插件信息”
- 使用 RePlugin.getPlugin() 方法,得到的是“当前正在运行的”插件信息(而非新插件的)
- 在这个“当前正在运行的”插件信息上,再调用 getPendingUpdate() 方法,则可以拿到这个“新版本插件信息”了。
代码说明一下:
// Fetch "Current Version" plugin.
PluginInfo pi = RePlugin.getPluginInfo("exam");
if (pi != null) {
// Fetch "New Version" plugin
PluginInfo newPi = pi.getPendingUpdate();
if (newPi != null) {
...
} else {
// No update
...
}
}