MCPcopy
hub / github.com/Tencent/Shadow

github.com/Tencent/Shadow @2.3.0 sqlite

repository ↗ · DeepWiki ↗ · release 2.3.0 ↗
2,869 symbols 7,904 edges 435 files 256 documented · 9%
README

Shadow

Android CI PRs Welcome

介绍

Shadow是一个腾讯自主研发的Android插件框架,经过线上亿级用户量检验。 Shadow不仅开源分享了插件技术的关键代码,还完整的分享了上线部署所需要的所有设计。

与市面上其他插件框架相比,Shadow主要具有以下特点:

  • 复用独立安装App的源码:插件App的源码原本就是可以正常安装运行的。
  • 零反射无Hack实现插件技术:从理论上就已经确定无需对任何系统做兼容开发,更无任何隐藏API调用,和Google限制非公开SDK接口访问的策略完全不冲突。
  • 全动态插件框架:一次性实现完美的插件框架很难,但Shadow将这些实现全部动态化起来,使插件框架的代码成为了插件的一部分。插件的迭代不再受宿主打包了旧版本插件框架所限制。
  • 宿主增量极小:得益于全动态实现,真正合入宿主程序的代码量极小(15KB,160方法数左右)。
  • Kotlin实现:core.loader,core.transform核心代码完全用Kotlin实现,代码简洁易维护。

支持特性

  • 四大组件
  • Fragment(代码添加和Xml添加)
  • DataBinding(无需特别支持,但已验证可正常工作)
  • 跨进程使用插件Service
  • 自定义Theme
  • 插件访问宿主类
  • So加载
  • 分段加载插件(多Apk分别加载或多Apk以此依赖加载)
  • 一个Activity中加载多个Apk中的View
  • 等等……

编译与开发环境

环境准备

建议直接用最新的稳定版本Android Studio打开工程。目前项目已适配Android Studio Arctic Fox | 2020.3.1, 低版本的Android Studio可能因为Gradle版本过高而无法正常打开项目。

然后在IDE中选择sample-appsample-host模块直接运行,分别体验同一份代码在正常安装情况下和插件情况下的运行情况。

选择sample-host直接运行

Shadow的所有代码都位于projects目录下的3个目录,分别是:

  • sdk包含SDK的所有代码
  • test包含SDK的自动化测试代码
  • sample包含演示代码

其中sample应该是大家体验Shadow的最佳环境。 详见sample目录中的README介绍。

自己写的测试代码出错?

以我们多年的插件环境下业务开发经验,插件框架是不可能一步到位实现完美的。 因此,我们相信大部分业务在接入时都是需要一定的二次开发工作。 Shadow现有的代码满足的是我们自己的业务现在的需求。得益于全动态的设计, 插件框架和插件本身都是动态发布的,插件包里既有插件代码也有插件框架代码, 所以可以根据新版本插件的需要同时开发插件框架。

例如,ShadowActivity没有实现全所有Activity方法,你写的测试代码可能用到了, 就会出现Method Not Found错误,只需要在ShadowActivity中实现对应方法就可以了。 大部分方法的实现都只是需要简单的转调就能工作正常。

如果遇到不会实现的功能,可以提Issue。最好附上测试代码。

后续开发

  • 原理与设计说明文档
  • 多插件支持的演示工程
  • 自动化测试用例补充
  • 开源包含下载能力的manager实现

贡献代码

详见CONTRIBUTING.md

许可协议

Tencent Shadow采用BSD 3-Clause License,详见LICENSE

个人信息保护规则声明

详见PRIVACY.md

Extension points exported contracts — how you extend this code

IHelloWorldImpl (Interface)
@author 林学渊 @email linxy59@mail2.sysu.edu.cn @date 2021/9/6 @description 给接口 IHelloWorld 包装一层生命周期 可参考 com.tencent.shadow [8 …
projects/sample/dynamic-apk/sample-hello-api/src/main/java/com/tencent/shadow/sample/api/hello/IHelloWorldImpl.java
PluginManagerImpl (Interface)
实现方需要实现的接口 @author cubershi [10 implementers]
projects/sdk/dynamic/dynamic-host/src/main/java/com/tencent/shadow/dynamic/host/PluginManagerImpl.java
SimpleIdlingResource (Interface)
(no doc) [3 implementers]
projects/test/lib/test-manager/src/main/java/com/tencent/shadow/test/lib/test_manager/SimpleIdlingResource.java
HelloFactory (Interface)
@author 林学渊 @email linxy59@mail2.sysu.edu.cn @date 2021/9/6 @description 宿主只能通过工厂模式获取 apk 中的类 @usage null [7 implementers]
projects/sample/dynamic-apk/sample-hello-api/src/main/java/com/tencent/shadow/sample/api/hello/HelloFactory.java
PluginManager (Interface)
使用方持有的接口 @author cubershi [8 implementers]
projects/sdk/dynamic/dynamic-host/src/main/java/com/tencent/shadow/dynamic/host/PluginManager.java
WhiteList (Interface)
此类包名及类名固定 classLoader的白名单 PluginManager可以加载宿主中位于白名单内的类
projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java
HelloWorldUpdater (Interface)
apk文件升级器 注意这个类不负责什么时候该升级 实现IHelloWorld的apk文件, 它只提供需要升级时的功能,如下载和向远端查询文件是否还可用。 [5 implementers]
projects/sample/dynamic-apk/sample-hello-api-holder/src/main/java/com/tencent/shadow/sample/apk/hello/HelloWorldUpdater.java
PluginManagerUpdater (Interface)
PluginManager文件升级器 注意这个类不负责什么时候该升级PluginManager, 它只提供需要升级时的功能,如下载和向远端查询文件是否还可用。 [6 implementers]
projects/sdk/dynamic/dynamic-host/src/main/java/com/tencent/shadow/dynamic/host/PluginManagerUpdater.java

Core symbols most depended-on inside this repo

addView
called by 97
projects/sample/source/sample-host-lib/src/main/java/com/tencent/shadow/sample/host/lib/HostAddPluginViewContainer.java
getApplicationContext
called by 78
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java
onCreate
called by 64
projects/sdk/dynamic/dynamic-host/src/main/java/com/tencent/shadow/dynamic/host/PluginManagerImpl.java
getPackageName
called by 58
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java
setContentView
called by 57
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowActivity.java
info
called by 55
projects/sdk/core/common/src/main/java/com/tencent/shadow/core/common/Logger.java
isInfoEnabled
called by 51
projects/sdk/core/common/src/main/java/com/tencent/shadow/core/common/Logger.java
getString
called by 46
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/MixResources.java

Shape

Method 2,331
Class 472
Interface 66

Languages

Java100%

Modules by API surface

projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/delegates/PackageManagerWrapper.java102 symbols
projects/sample/source/sample-plugin/third-party/slidingmenu/src/main/java/com/jeremyfeinstein/slidingmenu/lib/SlidingMenu.java76 symbols
projects/sample/source/sample-plugin/third-party/slidingmenu/src/main/java/com/jeremyfeinstein/slidingmenu/lib/CustomViewAbove.java67 symbols
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowActivityLifecycleCallbacks.java53 symbols
projects/sample/source/sample-plugin/third-party/slidingmenu/src/main/java/com/jeremyfeinstein/slidingmenu/lib/CustomViewBehind.java46 symbols
projects/test/dynamic/host/test-dynamic-host/src/main/java/com/tencent/shadow/test/dynamic/host/AndroidLogLoggerFactory.java40 symbols
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ResourcesWrapper.java40 symbols
projects/sdk/core/manager-db-test/src/androidTest/java/common/AndroidLogLoggerFactory.java40 symbols
projects/sample/source/sample-host/src/main/java/com/tencent/shadow/sample/host/AndroidLogLoggerFactory.java40 symbols
projects/sample/maven/host-project/introduce-shadow-lib/src/main/java/com/tencent/shadow/sample/introduce_shadow_lib/AndroidLoggerFactory.java40 symbols
projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/AndroidLogLoggerFactory.java40 symbols
projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java36 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add Shadow \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact