让「小程序」跑起真正的原生代码:ComboNative 多进程原生小程序运行时 · Alpha 首发

让「小程序」跑起真正的原生代码:ComboNative 多进程原生小程序运行时 · Alpha 首发

一个 Android 动态化框架:每个小程序都是原生 Kotlin/Compose、运行在独立进程、可与宿主各自独立混淆加固。框架运行时约 347 KB,一个功能完整的小程序包可低至 32.8 KB,内含三个小程序的完整 demo(release)仅 7.74 MB。

主库暂未开源,但已发布至 Maven Central,现开放 Alpha 抢先体验,可直接接入试用。本文较长,建议按小标题按需跳读:从「为什么做」到「怎么用」再到「边界在哪」,一次讲透。



TL;DR(30 秒速览)

如果你没时间读完全文,记住这几点就够了:

  • 它是什么 :一个 Android 动态化框架。每个「小程序」都是原生 Kotlin/Compose 代码 ,运行在独立子进程里,由宿主 App 动态下发、加载、治理。
  • 它解决什么 :传统单进程插件化的三大死结------不能独立混淆加固、内存泄漏难根治、崩溃会传染;同时又不像 JS 小程序那样有性能与能力天花板。
  • 凭什么能做到 :跨进程只走 AIDL 契约、只传字节不传类名 (→ 双方各自独立加固);每个小程序一个进程、关闭即杀进程 (→ 内存不泄漏、崩溃不传染);构建期静态生成占坑进程、0 Hook AMS/PMS(→ 稳定、随版本兼容)。
  • 有多轻 :框架运行时约 347 KB ;一个功能完整的记账小程序 .cbp32.8 KB ;含 3 个小程序的完整 demo(release)7.74 MB,框架本体占比 <5%。
  • 适合谁 :车机 / 座舱 / TV / 行业 PDA / Kiosk / 定制 ROM 等受控终端 ,以及需要代码资产保护 + 动态下发原生功能的第一方 / 合作方生态。
  • 不适合谁 :允许匿名任意第三方上传原生代码的开放市场(它不是强沙箱);iOS / 跨端;Google Play 内动态加载 Play 外可执行代码。
  • 现在能做什么 :主库暂未开源,但四个库已上 Maven Central 、示例仓库已开源,可直接接入体验,欢迎参与 Alpha 众测。

🚀 立即体验(不想读长文?先上手)

入口 链接
📥 示例 App 下载(免构建,装上就能玩) https://130.94.11.104:17558/down/9yiZ75pfO4QR.apk
🧩 示例小程序 .cbp 下载 小程序① · 小程序② · 小程序③
🔗 示例开源仓库(宿主 + 3 个原生小程序,可独立克隆构建) github.com/lnzz123/com...
📚 Maven 接入 io.github.lnzz123:combonative-engine:0.1.0-alpha01(及 abi/runtime/mini-sdk
🧰 打包插件(Gradle Plugin Portal) io.github.lnzz123.combonative-packer:0.1.0-alpha01

觉得有意思,欢迎点个 ⭐ Star、提 Issue,一起参与 Alpha 众测。想了解「它为什么这么设计」,继续往下读。


目录

  1. 一个真实的两难:先讲个故事
  2. 背景:为什么要做 ComboNative
  3. 它与 ComboLite 的关系
  4. 设计目标与核心取舍(含三方对比)
  5. 核心机制(原理层面)
  6. 轻量化:可复现的体积数据
  7. 十分钟实战:从宿主集成到跑起第一个小程序
  8. 真实安全边界与适用场景
  9. 选型:ComboLite 还是 ComboNative
  10. 常见问题 FAQ
  11. 当前状态
  12. 抢先体验与资源

〇、一个真实的两难:先讲个故事

设想你在做一台车机(或智能座舱 / 一体机 / 行业 PDA,任选其一)。产品经理提了三个看似平常、实则互相打架的需求:

  1. 要能动态下发功能。 车卖出去之后,「充电地图」「会员商城」「第三方生态应用」得能远程更新、按需安装,不可能每次都整机 OTA。
  2. 要原生的体验和能力。 中控大屏上任何一处卡顿、掉帧都会被放大成「这车真廉价」;而且要用到蓝牙、CAN、定位、摄像头这些底层能力,套一层 JS 容器既慢又处处受限。
  3. 要稳,还要安全。 车机开机就是几个月不重启;任何一个第三方模块的崩溃或内存泄漏,都不能影响到主 HMI;合作方的模块不能随便读你不想给的东西,你自家的核心代码也不能被轻易逆向。

于是你在两条老路之间反复横跳:

  • JS / 跨端小程序 ?满足了「动态下发 + 沙箱安全」,但性能和底层能力这关过不去,产品体验被容器拖住。
  • 传统原生插件化 ?性能和能力都有了,但不能给插件独立加固 (一混淆就崩)、插件崩溃会掀翻整个中控长时间运行内存越吃越多------对一台几个月不重启的设备,这几乎是定时炸弹。而且很多方案还在 Hook 系统私有 API,每次大版本升级都心惊胆战。

你会发现,没有一条现成的路能同时满足这三点。 这个「原生 vs 动态 vs 隔离」的三角矛盾,正是我做 ComboNative 的起点。它不试图重新发明 Android,而是重新组织 Android 已有的能力------用「多进程 + 静态占坑 + 窄契约」把这三个角落一次性照顾到。下面从头讲起。


一、背景:为什么要做 ComboNative

在做出 ComboNative 之前,我维护的是上一代单进程插件化框架 ComboLite(0 Hook / 0 反射、Compose-first,已开源并上线 Maven Central)。ComboLite 把单进程插件化的「干净加载」做到了相当完整的程度,但在推向企业级、生产级场景时,暴露出三个长在架构地基上、靠打补丁难以根治的结构性限制:

  • 难以独立混淆加固。 单进程插件化的本质是宿主与插件共享同一 ClassLoader、按类的全限定名(FQCN)在运行期互相链接。一旦对任一侧开启混淆/加固,类名被重命名后跨模块符号即无法解析。这使得「核心代码资产保护」------企业付费意愿最强的诉求之一------在该模型下基本无解。
  • 内存泄漏难以根治。 插件卸载依赖手动清理引用(ClassLoader、资源、静态持有、回调等),任一环节遗漏即造成泄漏。对车机、机顶盒、行业终端等长时间不重启的设备尤为致命。
  • 崩溃会传染。 插件与宿主同进程运行,一处未捕获异常可导致整个应用崩溃。

结论很明确:这些问题在单进程模型内已无太多优化空间,需要从进程模型层面重做。ComboNative 由此而来------它并非 ComboLite 的版本升级,而是同一技术脉络下、针对上述结构性缺陷重新设计的下一代运行时


二、它与 ComboLite 的关系

维度 ComboLite(单进程) ComboNative(多进程)
模型 单进程插件化,共享 ClassLoader,按 FQCN 跨插件链接 多进程「原生小程序」运行时,独立进程 + 独立 ClassLoader
混淆加固 跨插件按类名链接,难以独立混淆 跨进程只走契约、不传类名,宿主与小程序各自独立混淆加固
崩溃 插件崩溃波及宿主 子进程崩溃隔离 + 崩溃熔断
内存 卸载靠清理引用,易泄漏 关闭即杀进程,由操作系统整体回收
开源 已开源、已上 Maven Central 主库暂未开源(已上 Maven,开放 Alpha 体验)
成熟度 相对成熟,可用于生产 0.1.0-alpha01,抢先体验阶段

有两点想说明:

ComboLite 将持续保持开源。 它的纯净类加载、AAR→APK 打包插件、全局类索引、依赖图与链式重启等实现均可公开研读,是一份完整的插件化工程参考。对希望深入理解动态化原理的开发者,在读懂单进程模型的能力边界后,完全可以沿「多进程 + IPC 契约」的方向自行实现一套类似 ComboNative 的运行时。

ComboNative 主库暂不开源(考虑到其仍处于 Alpha 阶段及后续商业化规划),但框架的四个库已发布至 Maven、并提供完整的开源示例仓库,可先行接入体验。


三、设计目标与核心取舍

行业内的 Android 动态化长期在两类方案间权衡:

  • JS 小程序 / 跨端容器:沙箱安全、跨端一致、生态成熟;代价是 UI 经渲染桥、逻辑跨 JS↔Native 边界序列化,性能存在上限,底层能力受容器方开放节奏制约。
  • 传统原生插件化:性能接近原生;代价是前述的混淆、泄漏、崩溃传染问题,且许多方案依赖 Hook AMS/PMS 等系统私有 API。

ComboNative 的设计目标是取二者之长:以原生方式执行、以小程序方式下发与治理,并从架构层面消解上述缺陷。其核心设计与对应收益如下:

目标 实现方式 收益
独立混淆加固 跨进程仅传 apiId + 序列化字节,从不传类名 宿主与小程序可分别混淆、分别加固
崩溃隔离 每个小程序运行于独立子进程 崩溃只影响自身,宿主无感,另有熔断兜底
内存可控 关闭小程序即终止其进程 内存交由操作系统整体回收,杜绝泄漏累积
不依赖系统私有 API 构建期静态生成占坑组件与占坑进程 0 Hook AMS/PMS,全程公开 API,版本兼容性可控

安全模型需如实说明:ComboNative 采用受控准入 + 越权拦截 + 进程隔离并非强沙箱。小程序与宿主同 UID,原生代码可访问该进程可达的底层资源。因此它面向第一方 / 合作方,以及经签名白名单 + 审核准入的半可信生态,而非匿名任意第三方的开放市场。第七节会专门展开边界。

三方对比:JS 小程序 / 传统插件化 / ComboNative

把三条路放在一起看,取舍一目了然:

维度 JS 小程序 / 跨端容器 传统原生插件化 ComboNative
执行方式 JS + 渲染桥 原生 原生 Kotlin/Compose
性能上限 受桥与序列化限制 原生 原生
底层能力 受容器开放节奏制约 完整 完整(含 NDK)
崩溃隔离 容器级隔离 ❌ 同进程传染 进程级隔离 + 熔断
内存治理 容器回收 ❌ 手动清理易泄漏 关闭即杀进程
独立混淆加固 不涉及(JS) ❌ 按类名链接难混淆 只传字节,可独立加固
是否 Hook 系统 多数需 Hook AMS/PMS 0 Hook,全公开 API
安全强度 强沙箱 受控准入 + 拦截 + 隔离(非强沙箱
适用面 开放生态、跨端 通用 App 动态化 受控 / 半可信终端

一句话读懂这张表:JS 小程序赢在「安全 + 跨端」,传统插件化赢在「原生性能」,而 ComboNative 想在「原生性能」的基础上,把「隔离 + 内存治理 + 代码保护」也一起拿下------代价是它只面向来源可控的受控生态,且用一定的跨进程开销与资源占用作为交换。


四、核心机制(原理层面,不涉及内部实现)

4.1 占坑进程池:0 Hook 的多进程

Android 四大组件无法在运行期动态创建,系统只识别打包前 manifest 中静态声明的组件,android:process=":mpN" 亦由 manifest 决定。传统插件化为让插件组件被系统调度,普遍采用 Hook AMS/PMS + 占坑组件欺骗系统 的方案------能用,但依赖系统私有 API,每逢大版本升级都要重新适配。

ComboNative 的取向是不 Hook、不欺骗系统,只用公开 API,把动态性从「运行期骗系统」前移到「构建期造槽位」:

构建期预声明 N 组「占坑」组件、每组绑定一个独立进程 :mp1...:mpN;运行期需要运行小程序时,从进程池挑一个空闲槽位拉起;关闭时终止该进程、归还槽位。

这里的关键是:槽位是同质的、空的、通用的 ------不绑定任何具体小程序,如同酒店房间,谁来了都能住进去,走了就腾空。占坑组件、进程声明及配套 manifest 全部由构建期的 Gradle 插件自动生成,开发者无需手写。

代价需要如实说明:并发运行的小程序数量上限 = 预声明的槽位数launchMode 等静态属性对同质槽位统一。这是「不 Hook、只用公开 API」这条路必然的权衡------用可控的资源开销与灵活性约束,换长期的稳定性与版本兼容性。

4.2 AIDL 契约:只传字节、不传类名

多进程解决了隔离,但也带来通信问题。ComboNative 的答案是一层 AIDL + Parcelable 契约,并定下一条贯穿始终的铁律:

跨进程仅传递 apiIdapiVersion 与序列化后的 payload 字节;不传递 Class、类全名,也不传递任意可序列化对象。

宿主与小程序之间流动的永远是「数据」,而非「类型」。正因为两端从不按类名互相引用 ,宿主可以任意混淆自己的类、小程序也可以任意混淆自己的类,互不影响------这就是 ComboLite 做不到、而 ComboNative 能做到「独立混淆加固」的根本原因。 契约面越窄、越稳定,两端的演进就越自由。

此外,请求携带 apiVersion,能力可按兼容区间向后兼容地演进;宿主为每个小程序创建绑定其真实身份的通信端,调用方伪造身份字段会被真实身份覆盖。

4.3 四大组件跨进程代理

小程序内可正常使用 Activity、Service(含前台服务)、BroadcastReceiver、ContentProvider,均由占坑组件承载:

  • Activity 由占坑 ProxyActivity 承载,支持进程内栈式导航与 startActivityForResult 结果回传;
  • Service 由每槽位的代理池承载,支持前台服务(Android 14+ 的 foregroundServiceType 由宿主静态声明);
  • 静态广播由宿主主进程接收后唤醒目标小程序进程再转发;
  • ContentProvider 由宿主按 authority 路由并重写 URI 后转发至小程序进程,Cursor 结果经 CursorWindow 共享内存跨进程返回。

4.4 大 payload 的 fd 旁路

Binder 单次事务缓冲有限(约 1 MB 且与并发事务共享),大数据内联会触发 TransactionTooLargeException。ComboNative 在 IPC 边界做了处理:当 payload 超过 128 KiB ,自动改用 ParcelFileDescriptor 管道旁路(Binder 中仅传一个 fd),对业务代码完全透明,无需手动分片。

4.5 准入、熔断与进程回收

  • 安装准入 :解析 .cbp 元数据 → 签名白名单校验 → 版本比较(默认拒绝降级、升级校验签名一致防替换)→ 事务化落盘,启动可恢复;
  • 崩溃熔断:滑动窗口内崩溃次数达阈值即自动禁用该小程序,之后可一键恢复;
  • 进程健康:Binder death 探测子进程存活,任务哨兵在最近任务被移除时可靠回收进程与槽位。

架构概览

五、轻量化:可复现的体积数据

数据口径:0.1.0-alpha01,release / R8 混淆后。所有数字均可在开源示例仓库一键复现(命令见第十一节)。

5.1 框架运行时:约 347 KB

模块 AAR 体积 作用
combonative-abi 66.9 KB 契约层(AIDL + 序列化模型)
combonative-engine 202.4 KB 宿主主进程引擎:调度、API 桥、安装准入
combonative-runtime 53.7 KB 子进程运行时:dex 加载、占坑组件、资源加载
combonative-mini-sdk 23.9 KB 小程序开发面(运行期由宿主提供)
合计 ≈ 347 KB

打包插件 combonative-packer(165 KB)不计入------它只在构建期运行,不进运行时 APK。

5.2 单个小程序包:低至 32.8 KB

小程序 形态 .cbp(release) .cbp(debug)
miniapp-ledgerbook 纯逻辑 + 轻量 UI(记账) 32.8 KB 44.8 KB
miniapp-minihub 纯 Compose UI 97.7 KB 141.7 KB
miniapp-imagelab 含 NDK 原生图像处理 429.0 KB 497.0 KB

一个功能完整的记账小程序只有 32.8 KB。⚠️ 但不应把「几十 KB」当成所有小程序的恒定指标------体积取决于代码量、UI 复杂度、是否带 NDK 等,以上是特定示例、特定版本、特定口径的实测值。

为什么能这么小? 核心是「不重复打包宿主已有的东西」:小程序对框架 SDK 用 compileOnly(运行期由宿主提供,不进 .cbp),且不重复打包宿主已具备的 Compose / AndroidX 等公共依赖,.cbp 只装它自身独有的代码与资源。就像入住一间配齐家具的公寓,只需带自己的行李。

5.3 宿主整包:7.74 MB,框架占比不足 5%

构建类型 宿主 APK 体积
release(R8) 7.74 MB
debug 11.02 MB

这 7.74 MB 里绝大部分是 Compose / Material3 / AndroidX 等常规依赖(任何 Compose 应用都要带),四个框架运行时 AAR 合计约 347 KB、占比不足 5% 。也就是说,ComboNative 几乎不给宿主「增重」,整包大小主要由你自己的业务 UI 依赖决定。


六、十分钟实战:从宿主集成到跑起第一个小程序

以下代码均为公开 SDK 的使用方式(非主库内部实现),可对照开源示例仓库操作。前提:JDK 17、AGP 8.12+、Kotlin 2.2+、minSdk 24 / compileSdk 36。

6.1 配置宿主(一次性)

宿主 App 模块 build.gradle.kts

kotlin 复制代码
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("org.jetbrains.kotlin.plugin.compose")
    id("io.github.lnzz123.combonative-packer") version "0.1.0-alpha01"
}

dependencies {
    implementation("io.github.lnzz123:combonative-engine:0.1.0-alpha01")
}

comboNativeHost {
    miniApps {
        enabled.set(true)                                       // 自动把小程序打进 assets/miniapps/
        buildType.set(com.combonative.packer.PackageBuildType.DEBUG)
        dir.set("miniapps")
    }
    slots {
        enabled.set(true)
        count.set(3)          // 并发运行小程序上限
        servicesPerSlot.set(2)
    }
}

根项目 build.gradle.kts 声明要打包的小程序与签名:

kotlin 复制代码
plugins { id("io.github.lnzz123.combonative-packer") version "0.1.0-alpha01" }

combonativePacker {
    modules { module(":my-miniapp") }
    signing {
        keystorePath.set("/path/to/your.jks")
        keystorePassword.set("..."); keyAlias.set("..."); keyPassword.set("...")
    }
}

用生成的槽位清单初始化引擎(Application.onCreate):

kotlin 复制代码
class HostApp : Application() {
    override fun onCreate() {
        super.onCreate()
        ComboNative.initialize(
            application = this,
            config = ComboNativeConfig(
                slots = com.combonative.generated.GeneratedProcessSlots.SLOTS,
                hostApiProviders = listOf(/* 见 6.3 */),
                enforceSignature = false, // 调试期可关;生产必须 true
            ),
        )
    }
}

占坑组件由 packer 注入合并 manifest,无需手写;宿主 manifest 只需声明 android:name=".HostApp" 与自己的 launcher。

6.2 开发一个小程序(标准 Android Library)

kotlin 复制代码
// :my-miniapp/build.gradle.kts
android {
    namespace = "com.example.mymini"    // ← 这就是小程序的唯一 ID
    compileSdk = 36
    defaultConfig { minSdk = 24 }
    buildFeatures { compose = true }
}
dependencies {
    compileOnly("io.github.lnzz123:combonative-mini-sdk:0.1.0-alpha01") // 黄金法则:compileOnly
    implementation("androidx.compose.material3:material3:<version>")
}

入口类继承 MiniApp,基类 UI 中立:

kotlin 复制代码
class MyMiniApp : MiniApp() {
    override fun onCreateView(context: Context): View =
        ComposeView(context).apply {
            setContent { MiniTheme { Text("Hello from my first MiniApp!") } }
        }
}

manifest 元数据(复用标准清单字段:包名=唯一 ID、label=展示名、versionCode/Name=版本):

xml 复制代码
<manifest android:versionCode="1" android:versionName="1.0.0">
    <application android:label="我的第一个小程序">
        <meta-data android:name="combonative.miniapp.entryClass"
            android:value="com.example.mymini.MyMiniApp" />
        <meta-data android:name="combonative.miniapp.hostApis"
            android:value="account.getToken;ui.toast" />  <!-- 申请的宿主 API,分号分隔 -->
    </application>
</manifest>

6.3(可选)宿主暴露能力给小程序

能力目录完全由宿主定义,框架不内置:

kotlin 复制代码
// 宿主侧
private class AccountTokenProvider : HostApiProvider {
    override val apiId = "account.getToken"
    override fun handle(request: HostApiRequest) =
        HostApiResponse(HostApiResponse.ResultCode.OK, "token-for-${request.callerMiniId}".toByteArray())
}
// 小程序侧
val token = hostApi.invoke("account.getToken", apiVersion = 1).payload?.decodeToString()

授权分 NORMAL / DANGEROUS(需用户授权)/ HOST_SIGNATURE(仅同签名可用)三档。

6.4 构建、安装、运行

bash 复制代码
./gradlew :<你的宿主模块>:assembleDebug   # 自动把 .cbp 注入宿主 assets
unzip -l <宿主 APK 路径> | grep -i cbp    # 验证 .cbp 已进入 APK

宿主里释放 → 安装 → 启动:

kotlin 复制代码
ComboNative.installFromPackage(file, forceOverwrite = true)  // 调试期强制覆盖
ComboNative.launch(activity, "com.example.mymini")          // miniId = 包名

生产语义应改用 ComboNative.showInstallConfirm(context, file) 拉起安装确认页(展示名称/版本/申请 API/签名风险),用户确认后再落盘。

运行后:系统拉起 :mp0 子进程渲染出界面;系统「最近任务」里宿主与小程序各占一张卡片;划走小程序卡片,任务哨兵可靠回收该子进程。

🎬【视频 · 建议放】20~30 秒「进程隔离」硬核演示(最有说服力,强烈建议):①启动小程序 → 打开系统「最近任务」,展示宿主与小程序各占一张卡片 ;②在小程序里故意触发一个崩溃 → 小程序进程消失,宿主界面纹丝不动 ;③划走小程序卡片 → 用 adb shell ps | grep :mp 或开发者选项「正在运行的服务」展示子进程被回收。这段「崩了也不连累宿主」的对比是全篇最强的技术背书。

🖼️【截图 · 可选】Android Studio Profiler 或 adb shell ps 中出现独立 :mp0 子进程的截图,佐证「真·多进程」。

到这里,你已跑通完整闭环------你会发现,开发一个小程序,和开发一个普通 Android Library 模块几乎没有区别


七、真实安全边界与适用场景

与其把安全说成万能,不如把「能做到什么、做不到什么」讲清楚。

7.1 三层安全模型

  • 受控准入:签名白名单(不在白名单直接拒绝)、版本校验(默认拒绝降级、升级校验签名一致防替换)、安装确认页透明展示申请权限;
  • 越权拦截 :小程序访问能力的唯一通道是宿主 API 桥,一次调用依次校验「API 是否注册 → 版本是否匹配 → manifest 是否声明 → 是否已授权 → 审计 → 分发」;授权分 NORMAL / DANGEROUS / HOST_SIGNATURE 三档,其中 HOST_SIGNATURE 让某些能力只开放给同签名的自家小程序;身份由服务端按真实身份绑定,不可伪造;
  • 进程隔离:崩溃隔离(子进程崩溃不影响宿主)、崩溃熔断(反复崩溃自动禁用)、进程回收(Binder death 探测 + 任务哨兵)。

7.2 必须诚实说明的边界

  • 同 UID,不是强隔离。 小程序进程与宿主同 UID,原生代码能访问该进程可达的底层资源。进程隔离保证的是稳定性隔离 (崩溃/内存/生命周期),不是 OS 级安全沙箱 ;API 白名单拦得住「经 API 桥的越权调用」,拦不住蓄意的原生越权
  • 因此不适合匿名第三方开放市场。 若要「允许互联网上任意匿名开发者上传原生模块直接运行」,需要的是 OS 级强沙箱(独立 UID / seccomp / SELinux),这不是 ComboNative 的定位。它的价值前提是来源可控
  • 另:Android-only;不适合在 Google Play 内动态加载 Play 外可执行代码。

7.3 适用与不适用

✅ 适用: 车机 / 智能座舱、智能电视、行业 PDA、Kiosk、自动售货机等受控终端;定制 ROM、受控侧载平台;需要代码资产保护并动态下发原生功能的第一方 / 合作方生态;经签名白名单 + 审核准入的半可信小程序生态。

❌ 暂不适用: 匿名任意第三方上传原生模块的开放市场;需要 iOS / 跨端的场景;Google Play 内动态加载 Play 外可执行代码的场景。

举几个场景为什么适配:车机长时间不重启,进程隔离 + 关闭即回收根治泄漏,单模块崩溃不影响主 HMI;OTA 只需下发几十 KB 的 .cbp,无需整包升级;定制 ROM 以签名白名单构建半可信生态、第一方模块独立加固保护代码资产。


八、选型:ComboLite 还是 ComboNative

维度 ComboLite(单进程) ComboNative(多进程)
调用开销 进程内直接调用,极低 跨进程 IPC,有序列化/Binder 开销
混淆加固 难以独立混淆 各自独立混淆加固
崩溃影响 波及宿主 隔离 + 熔断
内存 卸载易泄漏 关闭即杀进程回收
并发/资源 不受槽位限制、更省内存 受槽位数限制、常驻内存更高
成熟度 相对成熟、已开源 Alpha、主库暂未开源

一句话判断法:你最怕的是「性能开销」还是「隔离与代码保护」?

  • 消费级 App、要成熟稳定、怕开销、模块多 → ComboLite
  • 受控终端、要独立加固 / 崩溃隔离 / 内存不泄漏、来源可控 → ComboNative

给 ComboLite 现有用户:不必急着迁移,它会继续开源维护。但如果你已撞上「想加固却一混淆就崩 / 内存持续上涨 / 一个插件崩溃带崩整个 App」这几堵墙,那正是 ComboNative 从架构层面要解决的问题------可先用开源示例评估「跨进程开销」是否可接受,再决定引入。


九、常见问题 FAQ

Q1:多进程听起来很重,每个小程序一个进程,内存吃得消吗? A:进程确实有常驻内存成本,这正是「并发上限 = 槽位数」这条设计的由来------你按设备资源预声明合适的槽位数,而非无限开进程。换来的是「关闭即杀进程、内存整体回收」,对长时间运行的设备反而更稳。资源受限时可减少槽位数;相比单进程,它用可控的内存换隔离与不泄漏,是一笔明确的权衡。

Q2:跨进程 IPC 的开销会不会拖慢小程序? A:UI 渲染、业务逻辑都在小程序自己的进程内原生执行,不过桥;只有「调用宿主能力」时才走一次 IPC。也就是说,开销只发生在明确的能力调用点上,而不是每一帧、每一次交互。大数据还有 fd 旁路兜底。对交互极其频繁、延迟极敏感的场景,可参考第八节选型建议。

Q3:小程序能用 Compose 吗?能用 NDK / .so 吗? A:都能。小程序是原生 Android Library,Compose、传统 View、Kotlin/Java、NDK 原生代码都支持。示例里的 miniapp-imagelab 就带了 NDK 图像处理。

Q4:.cbp 能像 APK 一样直接安装吗? A:不能,也不应该。.cbp 是 ComboNative 宿主专用的加载格式,只能由宿主安装、加载、运行,系统不会把它当独立 App。这是设计使然。

Q5:主库不开源,我接入了会不会被「锁死」? A:框架四个库已发布在 Maven Central,可正常依赖;示例仓库完全开源,接入方式、DSL、API 都是公开的。此外上一代 ComboLite 完整开源,原理与实现均可研读。你能清楚看到「怎么接、怎么用」,不存在黑盒锁定。

Q6:它和 Google 官方的 Dynamic Feature Module(动态功能模块)有什么区别? A:官方动态模块面向 Google Play 分发、由 Play 在安装期/按需 下发,仍运行在同进程、同 App 内,不提供进程隔离与独立加固,也依赖 Play 渠道。ComboNative 面向受控终端 / 自有分发,提供进程级隔离与独立加固,运行期由宿主自主治理,不依赖 Play。

Q7:现在是 Alpha,能上生产吗? A:建议先在非关键路径或内部项目试用、评估,欢迎参与众测反馈。API 在 Alpha 阶段仍可能调整,走向 1.0 的过程会尽量收敛并给出迁移说明。

Q8:iOS / 跨端支持吗? A:不支持,ComboNative 是 Android-only。需要跨端请考虑 JS / 跨端容器方案。


十、当前状态

  • 版本:0.1.0-alpha01
  • 四个运行时库已发布 Maven Central ,打包插件已上 Gradle Plugin Portal
  • 示例仓库已开源,含宿主 demo + 三个小程序,覆盖 Compose、纯逻辑、NDK 三类形态;
  • 完整中英文文档(快速开始 / 宿主集成 / 打包 / 核心 API / 组件 / 架构 / 安全 / 排障 / 性能与体积)。

发现问题欢迎提 Issue(附最小复现),或通过文末渠道联系我。你的反馈会直接影响它走向 1.0 的样子。


十一、抢先体验与资源

主库暂未开源,但已上传至 Maven,可直接接入体验,并欢迎在真实项目中试用、反馈问题与需求,帮我一起把它打磨到生产可用。

一键复现文中体积数据:

bash 复制代码
git clone --recurse-submodules https://github.com/lnzz123/combonative-samples.git
cd combonative-samples
export ANDROID_HOME=/path/to/android-sdk

./gradlew :host-demo:assembleRelease         # 宿主整包
./gradlew buildAllReleaseMiniApps            # 各小程序 .cbp(release / R8)
ls -la build/outputs/mini-app-packages/release/*.cbp

如果这套「原生 + 多进程 + 可独立加固」的思路对上了你的场景,欢迎试用、提 Issue、点个 Star;如果你更想搞懂它背后的原理、甚至自己造一套,也欢迎从开源的 ComboLite 读起。你的每一条反馈,都会直接影响它走向 1.0 的样子。

📌 本文所有数据基于 0.1.0-alpha01、release/R8 口径实测,随版本演进可能变化;Alpha 阶段 API 仍可能调整。

相关推荐
tmacfrank8 小时前
Android 17 重点新特性介绍
android
黄焖鸡能干四碗9 小时前
IT数据架构规划设计方案(PPT文件)
大数据·网络·数据库·人工智能·架构·区块链
YM52e9 小时前
鸿蒙 Flutter 渐变效果详解:LinearGradient、RadialGradient、SweepGradient
android·学习·flutter·华为·harmonyos·鸿蒙
●VON9 小时前
鸿蒙 PC Markdown 编辑器性能工程:中文输入与 10MiB 文档
华为·架构·编辑器·harmonyos·鸿蒙
禅思院10 小时前
Agent记忆管理,是一场工程上的平衡艺术
前端·架构·ai编程
-SOLO-10 小时前
Android 内存压力工具
android
o52788318410 小时前
校园一体化管理系统2.1、基于整洁四层架构 + DDD+CQRS 项目目录解读
后端·架构·c#·asp.net·visual studio
雅客李10 小时前
2026云手机延迟数据测评 安卓云手机远程操控实测哪个最好
android·智能手机
YM52e11 小时前
鸿蒙Flutter Card组件:Material设计风格卡片
android·学习·flutter·华为·harmonyos·鸿蒙