Convert Figma logo to code with AI

Tencent logoShadow

零反射全动态Android插件框架

7,420
1,302
7,420
34

Top Related Projects

8,125

A powerful Android Dynamic Component Framework.

A powerful and lightweight plugin framework for Android

6,752

Android Signature V2 Scheme签名下的新一代渠道包打包神器

5,043

A small framework to split app into small parts

Virtual Engine for Android(Support 14.0 in business version)

1,667

🔥🔥Qigsaw ['tʃɪɡsɔ] is a dynamic modularization library which is based on Android App Bundles(Do not need Google Play Service). It supports dynamic delivery for split APKs without reinstalling the base one.

Quick Overview

Shadow is an Android plugin framework developed by Tencent. It allows developers to dynamically load and run Android components as plugins, enabling hot-fixing, dynamic feature delivery, and modular app development without requiring app restarts or updates through app stores.

Pros

  • Enables dynamic loading of Android components, allowing for hot-fixing and feature updates without app restarts
  • Supports modular app development, improving code organization and maintenance
  • Provides a flexible plugin system that can be customized to fit specific project needs
  • Developed and maintained by Tencent, a major tech company with extensive experience in mobile app development

Cons

  • Steep learning curve for developers new to plugin architectures
  • May introduce additional complexity to the app's architecture
  • Potential performance overhead due to dynamic loading of components
  • Limited documentation and resources in English, as the project is primarily maintained in Chinese

Code Examples

  1. Loading a plugin:
val pluginManager = PluginManager.getInstance(context)
pluginManager.loadPlugin(pluginZipPath)
  1. Starting a plugin activity:
val intent = Intent()
intent.setClassName("com.example.plugin", "com.example.plugin.MainActivity")
pluginManager.startPluginActivity(context, intent)
  1. Accessing plugin resources:
val pluginResources = pluginManager.getPluginResources(pluginPackageName)
val drawableId = pluginResources.getIdentifier("icon", "drawable", pluginPackageName)
val drawable = pluginResources.getDrawable(drawableId)

Getting Started

To integrate Shadow into your Android project:

  1. Add the Shadow dependency to your build.gradle file:
dependencies {
    implementation 'com.tencent.shadow:shadow-core:2.1.1'
}
  1. Initialize the Shadow plugin manager in your application class:
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        PluginManager.init(this)
    }
}
  1. Load and use plugins in your app:
val pluginManager = PluginManager.getInstance(context)
pluginManager.loadPlugin("path/to/plugin.zip")

val intent = Intent()
intent.setClassName("com.example.plugin", "com.example.plugin.MainActivity")
pluginManager.startPluginActivity(context, intent)

For more detailed instructions and advanced usage, refer to the project's documentation on GitHub.

Competitor Comparisons

8,125

A powerful Android Dynamic Component Framework.

Pros of Atlas

  • More mature project with longer development history
  • Broader scope, supporting both dynamic component management and hotfix patching
  • Larger community and more extensive documentation

Cons of Atlas

  • Heavier framework with more complex implementation
  • Steeper learning curve for developers new to the system
  • Less frequent updates and maintenance compared to Shadow

Code Comparison

Atlas:

Atlas.getInstance().installBundleTransitively(bundleFile, false);
BundleImpl bundle = (BundleImpl) Atlas.getInstance().getBundle(bundleName);
bundle.start();

Shadow:

val pluginManager = Shadow.getPluginManager()
val installedPlugin = pluginManager.installPlugin(pluginZipFile)
pluginManager.loadPlugin(installedPlugin)

Both frameworks provide methods for installing and loading plugins, but Atlas offers a more granular approach with separate installation and start steps, while Shadow combines these operations in a more streamlined manner.

A powerful and lightweight plugin framework for Android

Pros of VirtualAPK

  • Simpler implementation and easier to integrate into existing projects
  • Supports a wider range of Android versions (4.0+)
  • More flexible plugin management with dynamic loading and unloading

Cons of VirtualAPK

  • Less active development and community support
  • Limited documentation and examples compared to Shadow
  • May have compatibility issues with newer Android versions

Code Comparison

VirtualAPK:

PluginManager pluginManager = PluginManager.getInstance(context);
pluginManager.loadPlugin(pluginPath);
Intent intent = new Intent();
intent.setClassName("com.example.plugin", "com.example.plugin.MainActivity");
startActivity(intent);

Shadow:

val pluginManager = PluginManager.getInstance(context)
pluginManager.loadPlugin(pluginPath)
val intent = Intent()
intent.setClassName("com.example.plugin", "com.example.plugin.MainActivity")
startActivity(intent)

Both frameworks use similar approaches for loading and launching plugin activities, but Shadow uses Kotlin while VirtualAPK uses Java. Shadow generally offers more advanced features and better performance optimization, while VirtualAPK provides a simpler implementation that may be easier for beginners to understand and integrate into existing projects.

6,752

Android Signature V2 Scheme签名下的新一代渠道包打包神器

Pros of Walle

  • Simpler setup and configuration process
  • Supports multiple channels for app distribution
  • Provides a user-friendly web interface for managing app releases

Cons of Walle

  • Limited plugin ecosystem compared to Shadow
  • Less flexibility for complex app architectures
  • Fewer advanced features for dynamic loading and resource management

Code Comparison

Shadow:

@ContainerFragment
class PluginContainerFragment : Fragment() {
    override fun onAttach(context: Context) {
        super.onAttach(context)
        // Plugin-specific initialization
    }
}

Walle:

public class WalleChannelWriter {
    public static void putChannel(File apkFile, String channel) throws Exception {
        // Write channel information to APK
    }
}

Shadow focuses on creating a flexible plugin system for dynamic loading of app components, while Walle primarily deals with app packaging and distribution across multiple channels. Shadow's code example demonstrates its plugin architecture, whereas Walle's code shows its channel writing functionality for APK files.

Both projects serve different purposes in the Android development ecosystem, with Shadow offering more advanced features for app modularization and dynamic loading, while Walle provides a streamlined solution for app distribution and channel management.

5,043

A small framework to split app into small parts

Pros of Small

  • Lighter weight and simpler implementation
  • Easier to integrate into existing projects
  • Supports hot-fixing without app updates

Cons of Small

  • Less comprehensive documentation
  • Smaller community and fewer updates
  • Limited support for complex plugin scenarios

Code Comparison

Small:

Small.setBaseUri("https://example.com/updates/");
Small.setUp(this);

Shadow:

PluginManager pluginManager = Shadow.getPluginManager();
pluginManager.loadPlugin("plugin.apk");
pluginManager.startPlugin("com.example.plugin");

Both Shadow and Small are Android plugin frameworks designed to enable dynamic loading and updating of app components. Shadow, developed by Tencent, offers a more robust and feature-rich solution with better documentation and ongoing support. It's particularly well-suited for large-scale applications with complex plugin requirements.

Small, on the other hand, provides a more lightweight approach that may be easier to implement in smaller projects. It offers hot-fixing capabilities, allowing for quick updates without requiring a full app update. However, its documentation is less comprehensive, and it may not be as suitable for more complex plugin scenarios.

In terms of code, Small's setup is generally simpler, while Shadow provides more granular control over plugin loading and management. The choice between the two depends on the specific needs of your project, considering factors such as complexity, scale, and required features.

Virtual Engine for Android(Support 14.0 in business version)

Pros of VirtualApp

  • More comprehensive virtualization, supporting full app-level virtualization
  • Broader compatibility with various Android versions and devices
  • More active community and frequent updates

Cons of VirtualApp

  • Potentially higher resource consumption due to full app virtualization
  • More complex implementation and integration process
  • May face legal challenges due to its nature of app cloning

Code Comparison

VirtualApp:

@Override
public void onCreate() {
    super.onCreate();
    VirtualCore.get().setHostPackageName("com.example.host");
    VirtualCore.get().initialize(this);
}

Shadow:

override fun onCreate() {
    super.onCreate()
    PluginManager.init(this)
    PluginManager.loadPlugin("com.example.plugin")
}

VirtualApp provides a more comprehensive virtualization approach, allowing full app cloning and running multiple instances of the same app. Shadow, on the other hand, focuses on plugin-based architecture, which can be lighter and more suitable for specific use cases.

VirtualApp's code shows initialization of the virtual core, while Shadow's code demonstrates plugin loading. This reflects their different approaches to app virtualization and plugin management.

1,667

🔥🔥Qigsaw ['tʃɪɡsɔ] is a dynamic modularization library which is based on Android App Bundles(Do not need Google Play Service). It supports dynamic delivery for split APKs without reinstalling the base one.

Pros of Qigsaw

  • Supports incremental updates, reducing download size for app updates
  • Provides a more flexible plugin management system
  • Offers better support for custom plugin loading strategies

Cons of Qigsaw

  • Less mature and less widely adopted compared to Shadow
  • Documentation is primarily in Chinese, which may be a barrier for non-Chinese speakers
  • Potentially more complex setup process for developers

Code Comparison

Shadow:

@PluginApplication(application = "com.example.MyApplication")
class PluginApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // Plugin initialization code
    }
}

Qigsaw:

public class PluginApplication extends QigsawApplication {
    @Override
    public void onCreate() {
        super.onCreate();
        // Plugin initialization code
    }
}

Both frameworks use similar approaches for initializing plugin applications, but Qigsaw uses Java while Shadow uses Kotlin. Shadow's annotation-based approach may be more concise, while Qigsaw's inheritance-based method might offer more flexibility for customization.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

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-app或sample-host模块直接运行,分别体验同一份代码在正常安装情况下和插件情况下的运行情况。

选择sample-host直接运行

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

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

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

兼容性

Shadow项目有较为完善的自动化测试,因此最新代码对外部环境的版本兼容性可以参考自动化测试的配置。

  • pr-check.yml 虚拟机自动化测试,包含Android测试机版本和编译环境JDK等版本。
  • pr-check-gradle-plugin.yml AGP兼容性测试。 其中指向的test_JDK17.sh和 test_JDK11.sh中定义了被测试的AGP版本。

自己写的测试代码出错?

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

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

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

后续开发

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

贡献代码

详见CONTRIBUTING.md

许可协议

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

个人信息保护规则声明

详见PRIVACY.md