Top Related Projects
A powerful Android Dynamic Component Framework.
A small framework to split app into small parts
Virtual Engine for Android(Support 14.0 in business version)
WMRouter是一款Android路由框架,基于组件化的设计思路,有功能灵活、使用简单的特点。
零反射全动态Android插件框架
🔥🔥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
VirtualAPK is an open-source plugin framework for Android developed by DiDi. It allows developers to dynamically load and run APK files as plugins within a host application, enabling modular app development and dynamic feature delivery without reinstalling the entire app.
Pros
- Enables dynamic loading of features without app reinstallation
- Supports most Android components and resources
- Minimal impact on app startup time and package size
- Allows for independent development and testing of plugin modules
Cons
- Requires careful management of plugin versioning and compatibility
- May introduce additional complexity in app architecture and deployment
- Limited documentation and community support compared to some alternatives
- Potential security concerns with dynamically loaded code
Code Examples
- Loading a plugin:
PluginManager pluginManager = PluginManager.getInstance(context);
String pluginPath = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/plugin.apk");
pluginManager.loadPlugin(new File(pluginPath));
- Starting an activity from a plugin:
Intent intent = new Intent();
intent.setClassName("com.example.plugin", "com.example.plugin.MainActivity");
startActivity(intent);
- Accessing resources from a plugin:
PluginManager pluginManager = PluginManager.getInstance(context);
Resources pluginResources = pluginManager.getResources("com.example.plugin");
int stringId = pluginResources.getIdentifier("app_name", "string", "com.example.plugin");
String appName = pluginResources.getString(stringId);
Getting Started
- Add VirtualAPK to your project's
build.gradle
:
dependencies {
implementation 'com.didi.virtualapk:core:0.9.8'
}
- Initialize VirtualAPK in your Application class:
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
PluginManager.getInstance(base).init();
}
}
- Load and use plugins as shown in the code examples above.
Competitor Comparisons
A powerful Android Dynamic Component Framework.
Pros of Atlas
- More comprehensive solution for large-scale app development and modularization
- Better support for multi-process architecture and resource isolation
- Provides a complete build system and runtime framework
Cons of Atlas
- Steeper learning curve due to its complexity
- Requires more extensive modifications to existing project structure
- Less flexible for smaller projects or simpler use cases
Code Comparison
Atlas:
@AtlasBundle(coverageRate = 0.8f)
public class BundleA extends AtlasBundleImpl {
@Override
public void onCreate() {
super.onCreate();
// Bundle initialization code
}
}
VirtualAPK:
public class PluginApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
PluginManager.getInstance(base).init();
}
}
Atlas focuses on a more structured approach with annotations and bundle-specific classes, while VirtualAPK uses a simpler initialization process. Atlas provides more control over bundle lifecycle and resource management, but VirtualAPK offers an easier integration path for existing projects.
Both solutions aim to solve similar problems in Android app modularization and dynamic loading, but Atlas is better suited for large-scale enterprise applications, while VirtualAPK is more appropriate for projects requiring a lightweight plugin system with minimal modifications to the existing codebase.
A small framework to split app into small parts
Pros of Small
- Simpler setup and integration process
- Supports both Android and iOS platforms
- More lightweight and less resource-intensive
Cons of Small
- Less active development and community support
- Limited documentation and examples compared to VirtualAPK
- Fewer advanced features for complex plugin scenarios
Code Comparison
Small:
Small.setBaseUri("https://example.com/updates/");
Small.setUp(this);
VirtualAPK:
PluginManager pluginManager = PluginManager.getInstance(this);
pluginManager.init();
File plugin = new File(Environment.getExternalStorageDirectory(), "plugin.apk");
pluginManager.loadPlugin(plugin);
Small focuses on simplicity and cross-platform support, making it easier to integrate for basic plugin functionality. However, it may lack some advanced features and has less community support compared to VirtualAPK.
VirtualAPK, developed by DiDi, offers more robust plugin management and advanced features, but with a steeper learning curve and Android-only support. It's better suited for complex plugin scenarios and large-scale applications.
Both projects aim to provide plugin frameworks for mobile apps, but they cater to different use cases and complexity levels. The choice between them depends on the specific requirements of your project and the desired level of plugin functionality.
Virtual Engine for Android(Support 14.0 in business version)
Pros of VirtualApp
- More comprehensive virtualization capabilities, including full app sandboxing
- Supports a wider range of Android versions and device types
- More active development and community support
Cons of VirtualApp
- Larger codebase and potentially more complex implementation
- May have higher resource usage due to full virtualization
- Potential legal concerns due to its powerful capabilities
Code Comparison
VirtualApp:
@Override
public void onCreate() {
super.onCreate();
VirtualCore.get().setHostPackageName("com.example.host");
VirtualCore.get().initialize(this);
}
VirtualAPK:
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
PluginManager.getInstance(base).init();
}
The code snippets show the initialization process for both frameworks. VirtualApp uses a centralized VirtualCore
class for setup, while VirtualAPK employs a PluginManager
instance. VirtualApp's initialization appears more configurable, allowing for host package name specification.
Both projects aim to provide plugin frameworks for Android, but VirtualApp offers more extensive virtualization features at the cost of increased complexity. VirtualAPK focuses on a lighter-weight approach to plugin management, which may be sufficient for many use cases while being easier to implement and maintain.
WMRouter是一款Android路由框架,基于组件化的设计思路,有功能灵活、使用简单的特点。
Pros of WMRouter
- Lightweight and focused on routing, making it easier to integrate into existing projects
- Supports both URI-based and custom scheme routing, offering more flexibility
- Provides a more straightforward API for defining and managing routes
Cons of WMRouter
- Limited to routing functionality, lacking the plugin system and dynamic loading capabilities of VirtualAPK
- May require additional libraries or components for advanced features like dynamic module loading
Code Comparison
WMRouter route definition:
@RouterUri(path = "/user/profile")
public class UserProfileActivity extends Activity {
// Activity implementation
}
VirtualAPK plugin loading:
PluginManager pluginManager = PluginManager.getInstance(context);
pluginManager.loadPlugin(pluginPath);
Summary
WMRouter is a lightweight routing solution that excels in simplicity and ease of use for navigation within an app. It's ideal for projects that primarily need routing functionality without the overhead of a full plugin system.
VirtualAPK, on the other hand, offers a more comprehensive solution for dynamic loading and plugin management, making it suitable for larger, more complex applications that require modular architecture and dynamic feature loading.
The choice between the two depends on the specific needs of the project, with WMRouter being more appropriate for simpler routing requirements and VirtualAPK for more advanced plugin-based architectures.
零反射全动态Android插件框架
Pros of Shadow
- More comprehensive plugin framework with better isolation and security
- Supports dynamic loading of resources and native libraries
- Better compatibility with Android system services and components
Cons of Shadow
- Steeper learning curve due to more complex architecture
- Potentially higher overhead for simple plugin scenarios
- Less mature community and documentation compared to VirtualAPK
Code Comparison
Shadow:
@ContainerFragment
class PluginFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_plugin, container, false)
}
}
VirtualAPK:
public class PluginActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plugin);
}
}
Shadow uses a more modern Kotlin-based approach with annotations for plugin components, while VirtualAPK relies on traditional Java inheritance for plugin activities. Shadow's approach offers more flexibility and better encapsulation of plugin logic.
Both frameworks aim to provide plugin functionality for Android apps, but Shadow offers a more robust and feature-rich solution at the cost of increased complexity. VirtualAPK, on the other hand, provides a simpler implementation that may be sufficient for basic plugin needs.
🔥🔥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 dynamic loading of native libraries, providing better flexibility for apps with native components
- Offers a more streamlined API for plugin management and lifecycle control
- Provides built-in support for resource isolation between plugins and the host app
Cons of Qigsaw
- Has a steeper learning curve due to its more complex architecture
- Requires more setup and configuration compared to VirtualAPK
- May have higher runtime overhead due to its resource isolation mechanisms
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);
Qigsaw:
SplitInstallRequest request = SplitInstallRequest.newBuilder()
.addModule("feature_module")
.build();
splitInstallManager.startInstall(request)
.addOnSuccessListener(sessionId -> {
// Module installed, start activity
});
Both VirtualAPK and Qigsaw are Android plugin frameworks, but they differ in their approach and features. VirtualAPK focuses on simplicity and ease of use, while Qigsaw offers more advanced features and better isolation at the cost of complexity. The choice between them depends on the specific requirements of your project and the level of plugin integration needed.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Android 9.0 supported! Please use the lastest release.
VirtualAPK is a powerful yet lightweight plugin framework for Android. It can dynamically load and run an APK file (we call it LoadedPlugin
) seamlessly as an installed application. Developers can use any Class, Resources, Activity, Service, Receiver and Provider in LoadedPlugin
as if they are registered in app's manifest file.
Supported Features
Feature | Detail |
---|---|
Supported components | Activity, Service, Receiver and Provider |
Manually register components in AndroidManifest.xml | No need |
Access host app classes and resources | Supported |
PendingIntent | Supported |
Supported Android features | Almost all features |
Compatibility | Almost all devices |
Building system | Gradle plugin |
Supported Android versions | API Level 15+ |
Getting started
Host Project
Add a dependency in build.gradle
in root of host project as following.
dependencies {
classpath 'com.didi.virtualapk:gradle:0.9.8.6'
}
Apply plugin in application module of build.gradle
.
apply plugin: 'com.didi.virtualapk.host'
Compile VirtualAPK in application module of build.gradle
.
compile 'com.didi.virtualapk:core:0.9.8'
Initialize PluginManager
in YourApplication::attachBaseContext()
.
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
PluginManager.getInstance(base).init();
}
Modify proguard rules to keep VirtualAPK related files.
-keep class com.didi.virtualapk.internal.VAInstrumentation { *; }
-keep class com.didi.virtualapk.internal.PluginContentResolver { *; }
-dontwarn com.didi.virtualapk.**
-dontwarn android.**
-keep class android.** { *; }
Finally, load an APK and have fun!
String pluginPath = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/Test.apk");
File plugin = new File(pluginPath);
PluginManager.getInstance(base).loadPlugin(plugin);
// Given "com.didi.virtualapk.demo" is the package name of plugin APK,
// and there is an activity called `MainActivity`.
Intent intent = new Intent();
intent.setClassName("com.didi.virtualapk.demo", "com.didi.virtualapk.demo.MainActivity");
startActivity(intent);
Plugin Project
Add a dependency in build.gradle
in root of plugin project as following.
dependencies {
classpath 'com.didi.virtualapk:gradle:0.9.8.6'
}
Apply plugin in application module of build.gradle
.
apply plugin: 'com.didi.virtualapk.plugin'
Config VirtualAPK. Remember to put following lines at the end of build.gradle
.
virtualApk {
packageId = 0x6f // The package id of Resources.
targetHost='source/host/app' // The path of application module in host project.
applyHostMapping = true // [Optional] Default value is true.
}
Developer guide
- API document wiki
- Sample project PluginDemo
- Read core library source code
- Read Release notes
Known issues
- Notifications with custom layout are not supported in plugin.
- Transition animations with animation resources are not supported in plugin.
Contributing
Welcome to contribute by creating issues or sending pull requests. See Contributing Guide for guidelines.
Who is using VirtualAPK?
License
VirtualAPK is licensed under the Apache License 2.0. See the LICENSE file.
Top Related Projects
A powerful Android Dynamic Component Framework.
A small framework to split app into small parts
Virtual Engine for Android(Support 14.0 in business version)
WMRouter是一款Android路由框架,基 于组件化的设计思路,有功能灵活、使用简单的特点。
零反射全动态Android插件框架
🔥🔥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.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot