前段时间需要调研哈shadow这个插件化框架,看官方的 github 的文档,一脸懵逼,文档也太少太乱了,文档编写者一看就是会写代码不会写文档的典型,很多细节都不说清楚,以为大家都知道他这框架的细节,🤦♂️
但是当时还是得继续研究,于是找了哈其他大佬的文档和demo,大概有用的是这些:
https://www.jianshu.com/p/8838d5c32c46:这个最靠谱
https://github.com/zhangyuChen1991/ShadowSample
https://juejin.cn/post/7264527436872155170
一直想总结哈,便于自己存档也方便大家集成,说下我总结的流程:
-
第一步先部署一个本地的Nexus Maven仓库,主要用于 shadow 库的存放,便于 demo 项目的依赖,可参考文档:https://blog.csdn.net/weixin_53599669/article/details/147700037,主要启动命令:
.\bin\nexus.exe //ES//SonatypeNexusRepository, 成功启动后默认端口的情况下的访问地址http://localhost:8081,按文档找到账号密码登录进去即可
Nexus 第二步就是 clone 腾讯的这个shadow库了https://github.com/Tencent/Shadow/tree/master,为避免后续更新后异常,备注哈我更新的详细信息(commitMsg: fix(core.gradle-plugin): 兼容AGP 8.9.0 commitId:f9dc3944944593c8d398f6ce5cb460f076d18d75)
-
clone项目到本地后 AS 打开,同步完成后只需修改local.properties里面的gpr.user(用户名)、gpr.key(密码)、gpr.url(链接)三个上面本地仓库配置即可
修改 maven 仓库地址 -
配置好后点击右边的 gradle 任务列表,找到
publish任务执行,没有异常等会儿应该就上传到本地仓库去了,如果成功了 shadow 源码的任务就告一段落了,它源码的其他东西可以先不用去研究了,太多项目,初次看到会懵逼的😄
推送项目到本地仓库 -
到 maven 仓库的网页里面的maven-snapshots库,比如
http://localhost:8081/#browse/browse:maven-snapshots确认一波 shadow 是否已经传上来了,如果传上来了应该类似下面这样的core、dynamic、plugin三个大库及里面的十来个小库:
shadow 三大库 -
然后随便点开一个具体的库的 pom 文件,能够获取到一个具体的shadow版本号,这个版本号是 shadow 上传时动态生成的,只需看一个库的就行,单次推送上来全部库的版本是一样的,比如我获取到的就是
local-f9dc3944-20250802.023341-1这个马上下面要用到
获取shadow版本号 -
现在需要去 clone 我整理的一个保姆级的 demo 项目,这个项目里面我分别建了一个主项目 app 和插件项目 app 以及附带必要的 shadow 库,大概如下:
项目介绍 -
demo库 clone 下来同步完成后,主要改
libs.versions.toml和settings.gradle两个文件的几个配置地方然后同步一波即可跑起来
修改为本地仓库shadow版本
修改为本地仓库配置信息 -
上面修改完就执行sample-manager-debug.apk的构建,这个主要是插件管理类,直接 AS 上选中项目sample-manager执行编译运行即可,运行完成后然后执行
adb push /Users/xxxx/Documents/xxxxx/MyShadowApplication/sample-manager/build/intermediates/apk/debug/sample-manager-debug.apk /data/local/tmp将sample-manager-debug.apk推到/data/local/tmp目录下面先放起(⚠️一般管理类没变化只需要执行一次这个操作就可以了)
sample-manager-debug.apk -
接着就是再执行插件包plugin-debug.zip的打包,这会把appPlugin这个插件 apk 及 shadow 的支持库loader和runtime都打进这个 zip 包里面,具体可以解压看看,操作方式是点击右边的 gradle 任务列表,找到
packageDebugPlugin任务执行,没有异常等会儿完成后应该在MyShadowApplication根目录下面生成 build/plugin-debug.zip 文件,执行adb push /Users/xxxx/Documents/xxxxx/MyShadowApplication/build/plugin-debug.zip /data/local/tmp将plugin-debug.zip推到/data/local/tmp目录下面也先放起(⚠️后面插件 apk 有改动后再执行一次这个操作就完成了插件的更新了)
plugin-debug.zip -
上面两步执行后应该如下:
插件相关文件 -
这个时候就完成了插件管理器和插件apk的准备,AS可以切换成 app 主工程的项目直接运行宿主 app 了,运行起来后点击"进入插件"这个按钮,没异常就能跳转到插件 app,点击插件 app 的"插件按钮点击"按钮,能正常 toast 说明运行完美
宿主 app
插件 app 好了,能够正常走完就是一个完整的漂亮流程了,具体就可以发挥想象去改插件及宿主了,比如插件可以有套检测逻辑动态下载更新等等,📢但是发现没,应该有点疑问吧,为啥要放在/data/local/tmp目录下,能不能换个目录,以及sample-manager-debug.apk这些一看不正规的名字能否改,以及宿主向插件传参等等,这些都是可以去阅读源码定制introduce-shadow-lib项目和sample-manager项目里面的变量和逻辑就能办到的,大概是InitApplication和SamplePluginManager类,具体从 demo 里面调用到的InitApplication.getPluginManager().enter入口追查下去即可
然后还有点重要的,如果插件里面有 vpnService 暂时不能这样插件化,因为shadow加载插件按我看到的代码及生成的东西理解是对 Android 一些主要及重要的组件做了包装,然而目前它并没对vpnService进行包装,如果需要得自己参照它包装 service 的方式代理包装,具体需要详细阅读代码然后实践了,这个就要评估这样做花的时间成本相关的了












