一、基本介绍

https://cloud.tencent.com/developer/article/2180899?from=15425&policyId=20240000&traceId=01jy6n5rtvtc4bn5k1p01fazt1&frompage=seopage (基本介绍)
https://www.nowcoder.com/discuss/518947418092711936 (深度解析)
https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650247043&idx=1&sn=bfc5b48b8d7b2f6c764c4e3da1bcd44a&chksm=88637eecbf14f7faa1292daeb13dc858e085f6b4620fd6ac825876d210999186056da9e664ed&scene=27 (郭霖)

二、源码demo运行

  • 遇到问题1
Tencent / Shadow 项目在我的android studio环境下编译失败:

Your build is currently configured to use incompatible Java 21.0.4 and Gradle 7.5. Cannot sync the project.

We recommend upgrading to Gradle version 8.9.

The minimum compatible Gradle version is 8.5.

The maximum compatible Gradle JVM version is 18.

Possible solutions:
 - Upgrade to Gradle 8.9 and re-sync
 - Upgrade to Gradle 8.5 and re-sync

上面提示Your build is currently configured to use incompatible Java 21.0.4 and Gradle 7.5. Cannot sync the project.,说我的java版本是21,与Gradle版本不匹配。然后我各种改什么gradle,kotlin版本会各种报错,最后发现是gradle 默认使用的sdk版本是21,修改一下android studio的默认配置为jdk17就行了:

三、源码分析(deepseek)

一、源码工程结构及作用

Shadow的代码组织在projects目录下,分为三个核心模块:

  1. sdk(框架核心实现) 158:
    • core:包含插件化核心逻辑。
      • loader:负责插件APK的加载和类管理。
      • runtime:实现代理Activity、Service等组件的运行时逻辑(如ShadowActivity)。
      • transform:字节码修改工具,编译期替换插件类的父类(如Activity → ShadowActivity)。
      • manager:管理插件生命周期和跨进程通信。
    • dynamic:实现框架自身的动态更新能力。
    • gradle-plugin:自定义Gradle插件,集成字节码修改到构建流程。
  2. sample(示例代码) 58:
    • sample-host:宿主应用,负责加载插件。
    • sample-manager:实现PluginManager,管理插件安装和更新。
    • sample-plugin:业务插件,可独立安装运行。
    • sample-constant:定义宿主与插件通信的常量。
  3. test(自动化测试) 8:
    • 覆盖插件加载、组件生命周期、资源隔离等场景的测试用例。

二、框架实现原理

1. 核心设计思想

  • 零反射/无Hook:通过"宿主代理"替代传统Hook方案,避免反射系统私有API,兼容Android高版本限制2410。
  • 全动态化:框架核心逻辑(manager/runtime/loader)自身作为插件动态加载,支持热更新16。
  • 字节码修改:编译期修改插件类继承关系(如Activity → ShadowActivity),使插件代码无需适配框架58。

2. 四大组件实现机制

  • Activity代理模型 27:
    • 宿主侧:注册PluginContainerActivity(代理Activity),通过AndroidManifest声明。
    • 插件侧:业务Activity在编译期父类被替换为ShadowActivity(非系统Activity)。
    • 生命周期转发PluginContainerActivity接收系统回调,通过ShadowActivityDelegate转发给插件Activity。
  • 其他组件:Service/ContentProvider/Broadcast采用类似代理机制,通过PluginContainerService等组件中转49。

3. 类加载与资源隔离

  • 双亲委派改造 13:

    • ApkClassLoader通过白名单控制类加载优先级:
    场景 加载策略
    白名单中的类(如宿主接口) 双亲委派(优先宿主ClassLoader)
    非白名单类 优先插件自身ClassLoader,失败时委派宿主
  • 资源隔离 19:

    • 通过ChangeApkContextWrapper创建插件独立Resources对象。
    • 修改AssetManager的加载路径指向插件APK,避免资源ID冲突。

4. 插件加载流程 69

  1. 宿主初始化
    • 复制Manager插件(manager.apk)到本地,加载PluginManager
  2. 动态加载Runtime/Loader
    • Manager插件通过Binder跨进程加载Runtime(代理逻辑)和Loader(类加载器)。
  3. 启动业务插件
    • Loader解析插件APK,创建ShadowApplication
    • 通过PluginContainerActivity启动目标插件Activity(实为代理转发)。

5. 跨进程通信(IPC)

  • Binder分层架构 69:
    • 宿主进程 ↔ PluginProcessService(插件进程)通过PpsController接口通信。
    • 关键对象(如PluginLoaderImpl)通过Binder跨进程传递。

三、核心技术亮点

  1. 字节码修改(Transform) 58:
    • 使用ShadowTransform在编译期修改插件字节码,替换父类(如Activity → ShadowActivity)、修复上下文引用(如getActivity())。
    • 工具:基于ASM/Javassist,集成至Gradle Plugin。
  2. 动态框架更新 610:
    • Manager/Runtime/Loader作为独立插件发布,宿主无需升级即可更新框架逻辑。
  3. 轻量化宿主
    • 宿主仅保留15KB核心代码(通信+代理),业务逻辑全动态加载14。
  4. 兼容性保障
    • 严格模式(StrictMode)下无非法API调用,通过Android 9+限制10。

四、局限性与适用场景

  • 局限性 14:
    • 接入复杂:需自定义Gradle插件,调试难度高。
    • 多进程限制:插件与宿主环境隔离,跨进程通信需显式设计。
    • 社区维护弱:官方已暂停迭代,需自行适配新需求。
  • 适用场景
    • 大型应用(如微信):模块动态更新、宿主轻量化。
    • 高兼容性需求:避免反射私有API,适配Android新版本。

总结

Shadow通过宿主代理模型 + 字节码修改 + 动态框架加载三重技术,实现了零反射的插件化方案。其工程结构分层明确(sdk/sample/test),核心价值在于全动态能力系统兼容性,但代价是较高的接入复杂度。对于深度插件化需求,Shadow仍是工业级优选,尤其适合需要长期兼容Android新版本的超级APP场景。


0 条评论

发表回复

您的电子邮箱地址不会被公开。