Mobile Development 18 min read

How iQIYI’s Neptune Enables Seamless Android Plugin Architecture

This article analyzes iQIYI’s Neptune plugin framework, explaining why pluginization is needed, the core technical principles of class and resource loading, lifecycle management, and how Neptune implements multi‑ClassLoader isolation, resource handling, context wrapping, and incremental updates for large‑scale Android apps.

iQIYI Technical Product Team
iQIYI Technical Product Team
iQIYI Technical Product Team
How iQIYI’s Neptune Enables Seamless Android Plugin Architecture

Why Pluginization Is Required

Rapid feature expansion leads to code bloat and the 65,536 method limit.

Increasing code size inflates APK size, which iQIYI strives to keep smaller than competitors.

High module coupling makes collaborative development difficult and extends compilation time.

Frequent app updates reduce user stickiness; faster, seamless updates are needed.

New features require dynamic upgrades; plugins enable hot deployment and real‑time updates.

Technical Foundations

Class Loading

Android loads classes through ClassLoader. The main loaders are:

BootClassLoader – loads system classes.

PathClassLoader – loads classes from installed apps.

DexClassLoader – loads dex/apk/jar from arbitrary paths (e.g., SD card).

Two loading mechanisms are commonly used:

Single ClassLoader : All plugin classes are injected into the host’s class loader (similar to Google MultiDex). Simple but prone to class‑collision issues.

Multiple ClassLoader : Each plugin gets its own ClassLoader, providing isolation and enabling hot deployment. Neptune adopts this approach.

Resource Loading

Plugins must load their own resources. The typical method creates a new AssetManager via the hidden addAssetPath() API and then builds a Resources instance:

try {
    AssetManager am = AssetManager.class.newInstance();
    Method addAssetPath = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
    addAssetPath.setAccessible(true);
    addAssetPath.invoke(am, pluginApkPath);
    Resources pluginResources = new Resources(am, hostResources.getDisplayMetrics(), hostResources.getConfiguration());
} catch (Exception e) {
    e.printStackTrace();
}

Resource strategies:

Isolation : Plugins can only access their own resources.

Merge : Host and plugin resources are combined, requiring ID conflict resolution.

Neptune uses a hybrid approach: plugins cannot access each other’s resources, but they can share host resources, avoiding risky host‑wide Resources hooks on fragmented ROMs.

Component Lifecycle

Android components (Activity, Service, BroadcastReceiver) are not declared in the host’s AndroidManifest. Neptune solves this with a proxy mechanism:

Creates a PluginClassLoader (subclass of DexClassLoader) per plugin.

Implements PluginContextWrapper to supply a custom Context that redirects class loading, resources, assets, and system services to the plugin.

Uses an InstrActivityProxy (or Instrumentation hook on Android P+) to instantiate the real plugin Activity via reflection and forward all lifecycle callbacks.

When Android P restricted access to Activity#attach, Neptune switched to hooking Instrumentation, a stable entry point across Android versions.

Neptune Framework Core Components

PluginClassLoader

: isolates classes per plugin. PluginContextWrapper: overrides getClassLoader(), getResources(), getAssets(), getSystemService(), and redirects intents for services/activities.

Activity/Service/Receiver proxy classes that handle registration, theme, launch mode, and transparent themes without host manifest entries.

Resource handling that fixes resource IDs across host and plugins by generating public.xml and ids.xml via Gradle scripts.

Only two lightweight hooks are used: Instrumentation and AssetManager, eliminating binder‑level risks and improving compatibility with OEM ROMs (e.g., Xiaomi, Vivo, Nubia).

Plugin Management Layer

On top of Neptune, iQIYI built a management layer that tracks plugin versions, dependencies, download policies, and patch updates. Each plugin version is represented by an OnLineInstance (mirroring backend data) and mapped to PluginLiteInfo in Neptune. The system selects the highest compatible version for installation.

State Machine

Plugins transition through a strict state machine: OriginalState → InstalledState. Incompatible versions are filtered out, and the highest compatible version is installed or upgraded.

Incremental Updates

To reduce download size, Neptune supports differential patches. The backend generates a diff package between the current and target versions; the client decides whether to apply the patch or download the full APK based on the locally installed version.

Key Features

Supports Activity, Service, and BroadcastReceiver without host manifest registration.

Activity proxy supports explicit/implicit launch, themes, launch modes, and transparent themes.

Service proxy supports start, stop, bind, and unbind operations.

BroadcastReceiver proxy supports static and dynamic registration.

Plugins can share host code and resources; resource IDs are fixed via generated public.xml / ids.xml.

Plugins may depend on each other; class loading respects dependency order.

ClassLoader and resource isolation prevent class conflicts and resource name collisions.

Host Activity containers can load plugin Fragments and Views.

Compatibility and Stability

Works on the majority of Android devices, including heavily fragmented OEM ROMs.

Minimal hooking: only Instrumentation and AssetManager are hooked.

Plugins can run in isolated processes, fully separated from the host.

No host PathClassLoader replacement, avoiding ROM‑specific risks.

Repository

https://github.com/iqiyi/Neptune

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Mobile DevelopmentAndroidplugin architectureResource ManagementclassloaderDynamic LoadingNeptune
iQIYI Technical Product Team
Written by

iQIYI Technical Product Team

The technical product team of iQIYI

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.