Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
iReaderAndroid edited this page Aug 25, 2016 · 6 revisions

欢迎使用ZeusPlugin

本项目为掌阅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页面同步下载,下载完成后即可加载使用。这时插件就可以是FragmentViewActivity等等。

补丁使用的定位

解决某个版本发布后的bug,或者是更新某个功能。由于代码会进行混淆,一个补丁通常只能对应一个版本。

插件补丁框架的核心思想

  • 替换系统使用的ClassLoader,通过阅读源码发现系统反射四大组件都是用的ContextImpl中的mPackageInfo中的mClassLoader成员变量。所以为了能让系统生成四大组件,我们通过反射修改了mClassLoader成员变量。补丁原理则是ClassLoader优先查找补丁中的类,如果存在则返回,然后再查找原宿主中的类,我们是通过反射的方式设置宿主ClassLoaderparent成员来完成的。
  • 替换系统获取资源用到的Resources对象并使该对象可以访问到所有插件和补丁的资源,Resources是通过AssetManager来访问资源的。系统的Resources对象是ContextImplmPackageInfo中的mResources成员。因此我们生成了一个PluginResources对象并创建一个可以访问所有插件的AssetManager,反射调用addAssetPath将插件/补丁的路径都添加上。 通过反射修改了mResources成员变量。但是部分手机是通过获取调用Activity/Application中的getResources来访问,我们重写该方法,并返回生成的PluginResources

以上就是我们的核心,修改生成类和资源的成员变量

使用步骤

  1. 使原应用程序的Application继承ZeusBaseApplication。或者将ZeusBaseApplication代码拷贝至自己的Application中。具体参考app中的MyApplication
  2. 使原应用程序的Activity都继承ZeusBaseActivity。或者将ZeusBaseActivity代码拷贝至自己的Activity中。具体参考app中的MainActivity
  3. 内置的插件应放入assets目录中。插件的命名以PluginConfig.EXP_PLUG_PREFIX为前缀,以PluginConfig.PLUGINWEB_APK_SUFF为结尾。
  4. 内置的插件必须在插件项目的assets中添加PluginConfig.PLUGINWEB_MAINIFEST_FILE(即plugin.meta)文件,该文件为插件的配置文件。配置如插件名称(name),插件版本(version),插件支持的宿主最低版本(minVersion),插件的入口类名(mainClass,可不写)。具体参考testplugin例子。
  5. PluginConfig中是一些可以配置的信息,建议除了内置插件目录以外都不要修改。
  6. 请将当前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'表示资源packageID0x7d开头。
  7. 插件或补丁的资源packageID不能与其他插件或者是宿主相同。具体如何设置请参考testplugin中的build.gradle
  8. app模块中的buil.gradle中的buildJar方法拷贝到你的build.gradle中,这个方法是用来生成插件的sdk,生成sdk的jar文件在build/libs路径下, 把生成的jar放到插件项目的sdk-jars,要把什么类放到sdk中,请对该方法进行修改。具体参考testplugin
  9. 请将插件的AndroidManifest.xml中有关的配置添加到宿主中,包括四大组件、权限申请、meta-data等,为了插件的扩展也可以在宿主中预定义一些组件。
  10. 插件和补丁有支持的宿主version code,minVersion为支持的最小版本,maxVersion为支持的最大版本,都是包含关系。如果要生效,这个不能写错!!

以下是补丁相关的。补丁与插件类似,只不过补丁把实时加载的功能去掉了。如果项目只运行在android 4.4及以上(art虚拟机,部分低于4.4的手机也可以去掉),则以下忽略,以上就已经支持补丁了,可以直接运行app模块,不需要以下的额外操作。

  1. 如果要支持bug fix的补丁功能,请增加zeusplugin:patch-gradle-plugin:1.0.0依赖,并将project的build.gradle中的带有//-----补丁相关-------的相关配置移植到你的项目里。如果你的项目只支持android 4.4及以上时(比如内置应用),不需要按照第当前移植即可支持bug fix补丁功能。具体请查看testhotfix模块。具体插件实现源码可以查看PatchPluginForZeus
  2. bug fix的补丁需要以PluginConfig.EXP_PLUG_HOT_FIX_PREFIX为开头,补丁apk中res文件夹中必须有实际的资源,实在没有就随便写个 com.android.internal.util.Predicate要保留,故意让所有的类中都包含这个类,这个类系统也定义了,所以dalvik虚拟机生成dex的时候会给当前记一个标记,这样补丁才能实现。
  3. 插件与补丁都需要先安装,插件可以任意时刻进行加载,补丁则下次启动由框架加载,不提供实时加载,实时加载之后你的内存中的对象可能就会乱套了。插件与补丁的安装代码如下:PluginManager.getPlugin(pluginName).install();
  4. 如果宿主被混淆请打补丁包时请保持补丁内的混淆结果与宿主一致,具体方式可自行搜索。
  5. android 4.4以下的手机中,补丁只在宿主的release包才生效,请在release包中进行测试。

也可以参考请看下面这篇文章: ZeusPlugin第一个插件

AltStyle によって変換されたページ (->オリジナル) /