Shadow插件框架学习
简介
Shadow是一个腾讯自主研发的Android插件框架,与市面上其他插件框架相比,Shadow主要具有以下特点:
- 复用独立安装App的源码:插件App的源码原本就是可以正常安装运行的。
- 零反射无Hack实现插件技术:从理论上就已经确定无需对任何系统做兼容开发,更无任何隐藏API调用,和Google限制非公开SDK接口访问的策略完全不冲突。
- 全动态插件框架:一次性实现完美的插件框架很难,但Shadow将这些实现全部动态化起来,使插件框架的代码成为了插件的一部分。插件的迭代不再受宿主打包了旧版本插件框架所限制。
- 宿主增量极小:得益于全动态实现,真正合入宿主程序的代码量极小(15KB,160方法数左右)。
- Kotlin实现:core.loader,core.transform核心代码完全用Kotlin实现,代码简洁易维护。
用网上的一个图表示就是:
Demo工程分析
部分Module的注释
-
sample-host
是宿主应用 -
sample-manager
是插件管理器的动态实现 -
sample-plugin/sample-loader
是loader的动态实现,业务主要在这里定义插件组件和壳子代理组件的配对关系等。 -
sample-constant
是在前3者中共用的相同字符串常量。 -
sample-plugin/sample-runtime
是runtime的动态实现,业务主要在这里定义壳子代理组件的实际类。 -
sample-plugin/sample-app-lib
是业务App的主要代码,是一个aar库。 -
sample-plugin/sample-normal-app
是一个apk模块壳子,将sample-app-lib
打包在其中,演示业务App是可以正常安装运行的。 -
sample-plugin/sample-plugin-app
也是一个apk模块壳子,同样将sample-app-lib
打包在其中,但是额外应用了Shadow插件,生成的apk不能正常安装运行。
工程编译
运行sample-host开始编译,Release版和Debug流程一样,这里只分析Debug版。
在/sdk/core/gradle-plugin目录下有个自定义的gradle插件ShadowPlugin,在sample-plugin-app的build.gradle中apply进来。ShadowPlugin主要做了以下几件事:
- 在编译期间通过字节码注入的方式将插件apk中一些类(比如Activity、Service等等)转成指定的一些类(比如ShadowActivity、ShadowService等等)
plugin.extension.registerTransform(ShadowTransform(
project,
classPoolBuilder,
{
shadowExtension.transformConfig.useHostContext }
))
- 创建shadow以及packagePlugin属性,并在sample-plugin-app的build.gradle中配置好runtime、loader、plugin的相关信息。
- 通过createPackagePluginTask以及createGenerateConfigTask创建两个gradle任务。createGenerateConfigTask任务的作用是将sample-runtime-debug.apk、sample-loader-debug.apk、sample-plugin-app-debug.apk的信息写到配置文件config.json中;createPackagePluginTask的作用是将sample-runtime-debug.apk、sample-loader-debug.apk、sample-plugin-app-debug.apk以及config.json打包成一个zip压缩包。
config.json长这样子:
{
"compact_version":[1,2,3],"pluginLoader":{
"apkName":"sample-loader-debug.apk","hash":"3BED30B04F62AFC50DAC0E936FDFB6DC"},"plugins":[{
"partKey":"sample-plugin-app","apkName":"sample-plugin-app-debug.apk","businessName":"sample-plugin-app","hash":"36FA91