-
Notifications
You must be signed in to change notification settings - Fork 179
Home
本项目为掌阅iReader团队推出的ZeusPlugin
插件框架产品项目,ZeusPlugin
为插件框架的所有代码,app
为测试插件与补丁的项目demo,testplugin
为插件demo, testhotfix
为补丁demo
。绝大部分核心代码都在PluginManger.java
中。PluginManager
也是入口类,核心方法是inite
初始化、loadLastVersionPlugin
加载插件、reloadInstalledPluginResources
加载插件与补丁的资源、loadHotfixPluginClassLoader
加载补丁的类。插件与补丁更新的最小单位是java
类(不局限四大组件)。
提高某些功能的升级率,使功能可以不通过安装新apk版本进行更新,可以实现wifi/移动环境下用户无感知的更新功能。如果电商类的网页,可以通过url告知客户端使用哪个插件并可以指定最低版本,然后客户端发现存在符合的插件就加载使用。如:http//www.baidu.com/a.php?p=zeusplugin_test&pversion=2
,表示该页面使用zeusplugin_test
插件,插件的最低版本号为2
。宿主发现存在符合的插件则加载并将该url传给插件,不存在则进入下载流程,下载完成后即可加载。插件的下发可以通过push
或者轮训的方式预下载增量更新包,或者进入loading页面同步下载,下载完成后即可加载使用。这时插件就可以是Fragment
、View
、Activity
等等。
解决某个版本发布后的bug,或者是更新某个功能。由于代码会进行混淆,一个补丁通常只能对应一个版本。
- 替换系统使用的
ClassLoader
,通过阅读源码发现系统反射四大组件都是用的ContextImpl
中的mPackageInfo
中的mClassLoader
成员变量。所以为了能让系统生成四大组件,我们通过反射修改了mClassLoader
成员变量。补丁原理则是ClassLoader
优先查找补丁中的类,如果存在则返回,然后再查找原宿主中的类,我们是通过反射的方式设置宿主ClassLoader
的parent
成员来完成的。 - 替换系统获取资源用到的
Resources
对象并使该对象可以访问到所有插件和补丁的资源,Resources是通过AssetManager来访问资源的。系统的Resources
对象是ContextImpl
的mPackageInfo
中的mResources
成员。因此我们生成了一个PluginResources
对象并创建一个可以访问所有插件的AssetManager
,反射调用addAssetPath
将插件/补丁的路径都添加上。 通过反射修改了mResources
成员变量。但是部分手机是通过获取调用Activity/Application
中的getResources
来访问,我们重写该方法,并返回生成的PluginResources
。
以上就是我们的核心,修改生成类和资源的成员变量。
- 使原应用程序的
Application
继承ZeusBaseApplication
。或者将ZeusBaseApplication
代码拷贝至自己的Application中。具体参考app
中的MyApplication
- 使原应用程序的Activity都继承
ZeusBaseActivity
。或者将ZeusBaseActivity
代码拷贝至自己的Activity中。具体参考app中的MainActivity
- 内置的插件应放入assets目录中。插件的命名以
PluginConfig.EXP_PLUG_PREFIX
为前缀,以PluginConfig.PLUGINWEB_APK_SUFF
为结尾。 - 内置的插件必须在插件项目的assets中添加
PluginConfig.PLUGINWEB_MAINIFEST_FILE(即plugin.meta)
文件,该文件为插件的配置文件。配置如插件名称(name),插件版本(version),插件支持的宿主最低版本(minVersion),插件的入口类名(mainClass,可不写)。具体参考testplugin
例子。 -
PluginConfig
中是一些可以配置的信息,建议除了内置插件目录以外都不要修改。 - 请将当前aapt目录下
aapt.exe
拷贝到sdk目录下的build-tools
中的正在使用的打包工具,替换原有的aapt.exe, 该aapt.exe
是基于6.0源码编译,包含windows、mac和linux(64位)版本。测试替换23.0.2、23.0.3都没有问题。该aapt.exe
还集成了资源混淆功能。需要在build.gradle
中进行配置。 如下:aaptOptions.additionalParameters '--PLUG-resoure-proguard', '--PLUG-resoure-id', '0x7d'
'--PLUG-resoure-proguard'
表明开启资源混淆,可以不写,不写表示不开启资源混淆,'--PLUG-resoure-id'
表示设置资源的packageID,'0x7d'
表示资源packageID
为0x7d
开头。 - 插件或补丁的资源
packageID
不能与其他插件或者是宿主相同。具体如何设置请参考testplugin中的build.gradle
。 - 将
app
模块中的buil.gradle
中的buildJar
方法拷贝到你的build.gradle
中,这个方法是用来生成插件的sdk,生成sdk的jar文件在build/libs
路径下, 把生成的jar放到插件项目的sdk-jars
,要把什么类放到sdk中,请对该方法进行修改。具体参考testplugin
。 - 请将插件的
AndroidManifest.xml
中有关的配置添加到宿主中,包括四大组件、权限申请、meta-data等,为了插件的扩展也可以在宿主中预定义一些组件。 - 插件和补丁有支持的宿主version code,minVersion为支持的最小版本,maxVersion为支持的最大版本,都是包含关系。
如果要生效,这个不能写错!!
以下是补丁相关的。补丁与插件类似,只不过补丁把实时加载的功能去掉了。如果项目只运行在android 4.4及以上(art虚拟机,部分低于4.4的手机也可以去掉),则以下忽略,以上就已经支持补丁了,可以直接运行app模块,不需要以下的额外操作。
- 如果要支持bug fix的补丁功能,请增加
zeusplugin:patch-gradle-plugin:1.0.0
依赖,并将project的build.gradle
中的带有//-----补丁相关-------
的相关配置移植到你的项目里。如果你的项目只支持android 4.4及以上时(比如内置应用),不需要按照第当前移植即可支持bug fix补丁功能。具体请查看testhotfix
模块。具体插件实现源码可以查看PatchPluginForZeus - bug fix的补丁需要以
PluginConfig.EXP_PLUG_HOT_FIX_PREFIX
为开头,补丁apk中res文件夹中必须有实际的资源,实在没有就随便写个com.android.internal.util.Predicate
要保留,故意让所有的类中都包含这个类,这个类系统也定义了,所以dalvik虚拟机生成dex的时候会给当前记一个标记,这样补丁才能实现。 - 插件与补丁都需要先安装,插件可以任意时刻进行加载,补丁则下次启动由框架加载,不提供实时加载,实时加载之后你的内存中的对象可能就会乱套了。插件与补丁的安装代码如下:
PluginManager.getPlugin(pluginName).install();
- 如果宿主被混淆请打补丁包时请保持补丁内的混淆结果与宿主一致,具体方式可自行搜索。
- android 4.4以下的手机中,补丁只在宿主的release包才生效,请在release包中进行测试。
也可以参考请看下面这篇文章: ZeusPlugin第一个插件