Реализация Plugin-архитектуры мобильного приложения
Plugin-архитектура — шаг дальше модульной. Если в модульной архитектуре все модули известны на этапе компиляции и собираются в единый бинарник, то plugin-архитектура предполагает, что части приложения могут быть добавлены, заменены или обновлены независимо от основного приложения — иногда в рантайме.
Это нужно не всегда. Конкретные сценарии: приложение-платформа с партнёрскими расширениями, super app где мини-программы — это плагины, корпоративная MDM-система где компания-клиент добавляет свои модули.
Как это работает на Android
На Android динамическая загрузка кода — реальность через DexClassLoader. Плагин — это APK или DEX-файл, загруженный в рантайме:
val pluginApkPath = File(context.filesDir, "plugin-v2.apk").absolutePath
val classLoader = DexClassLoader(
pluginApkPath,
context.codeCacheDir.absolutePath,
null,
context.classLoader
)
val pluginClass = classLoader.loadClass("com.plugin.FeatureImpl")
val plugin = pluginClass.getDeclaredConstructor().newInstance() as PluginContract
plugin.initialize(pluginContext)
PluginContract — интерфейс, который плагин имплементирует. Основное приложение знает только об интерфейсе, не о реализации. Плагин скачивается с сервера, верифицируется по цифровой подписи (JarVerifier или кастомная верификация через SHA-256), кладётся в filesDir, загружается.
Google Play Integrity API — для проверки того, что скачанный плагин не был подменён. IntegrityManager.requestIntegrityToken() перед загрузкой плагина подтверждает целостность запроса.
Ограничение. App Store (iOS) запрещает динамическую загрузку исполняемого кода — guideline 2.5.2. На iOS plugin-архитектура означает либо compile-time плагины (все известны при сборке, подключаются через протоколы), либо интерпретируемый контент (JavaScript через JavaScriptCore, Lua, WebAssembly) — это не нативный код и не нарушает правила.
iOS: plugin через протоколы и JavaScriptCore
На iOS «плагин» в смысле динамически загружаемого кода невозможен без джейлбрейка. Но plugin-архитектуру можно реализовать через:
1. Protocol-based compile-time plugins. Каждый плагин — Swift Package, реализующий PluginProtocol. Приложение компилируется со всеми плагинами, но активирует нужные через конфиг. Плагины изолированы через модули, доступ к API хоста — только через протокол.
2. JavaScriptCore как runtime. Плагин — JavaScript-файл, скачанный с сервера и исполняемый через JSContext. Хост регистрирует нативные функции как JS-объекты: context["nativeAPI"] = nativeAPI as AnyObject. Скорость выполнения — приемлемая для бизнес-логики, неприемлемая для рендеринга. Именно так работают мини-программы в WeChat и некоторых super app.
3. WebAssembly. С iOS 14+ WKWebView выполняет WASM через JavaScript engine. Плагин компилируется в WASM (из C++, Rust, AssemblyScript), выполняется в изолированной среде. Взаимодействие с нативным кодом — через WASM imports/exports.
Версионирование и совместимость плагинов
Самая сложная часть plugin-архитектуры — не загрузка кода, а управление совместимостью. Приложение v2.5 должно запустить плагин, написанный под v2.0 API, и не упасть на плагине v2.6, который ожидает несуществующего API.
Решение — явное версионирование контракта. PluginContract имеет minHostVersion и targetHostVersion. При загрузке плагина хост проверяет совместимость перед initialize(). Устаревшие версии API помечаются @Deprecated и поддерживаются в течение двух мажорных версий.
Кейс. Корпоративный super app для ритейла: основное приложение — авторизация, навигация, общий UI. Плагины — StockPlugin (складской учёт), CRMPlugin (работа с клиентами), AnalyticsPlugin (дашборды). Каждый плагин разрабатывается отдельной командой, загружается через MDM при первом запуске приложения сотрудником. Android: DexClassLoader с верификацией подписи. iOS: compile-time плагины через локальные SPM пакеты, активация через feature flags. Обновление плагина — без обновления основного приложения в Google Play (через собственный сервер дистрибуции для корпоративных устройств).
Сроки
| Тип системы | Ориентировочные сроки |
|---|---|
| Compile-time plugin система (iOS + Android) | 8–14 недель |
| Runtime plugin система (Android) + JS-плагины (iOS) | 4–7 месяцев |
| Полноценная платформа с маркетплейсом плагинов | 8–14 месяцев |
Стоимость рассчитывается индивидуально. Plugin-архитектура — решение для сложных платформ; для стандартных продуктов она избыточна и усложняет разработку без выгоды.







