何时使用 Native Mods
在需要以下任一能力时,选择 Native Mod 而非 Script Mod:- 注册新的服务实现 — 通过按优先级排序的服务注册表替换或增强 Aether 内置服务。
- 用完整 Compose 代码包裹或替换 Compose 组件 — Script 组件使用声明式 UI 树;Native 组件则提供不受限的 Jetpack Compose。
- 访问宿主方法未暴露的 Android 平台 API —
Context、PackageManager、平台传感器等。 - 对性能敏感的操作 — 受益于在应用进程中直接运行、经编译优化的 Kotlin。
- 通配操作拦截(
"*")— 拦截通过 mod kernel 分发的每一个操作。
AetherNativeMod 接口
每个 Native Mod 入口类都实现此接口:
onLoad 在进程启动加载 mod 时调用一次。接口定义了 onUnload,但当前 Native Mod 管理器不会调用它。
AetherNativeModContext
传入onLoad 的 context 参数是访问 mod kernel 全部能力的入口:
DEX 编译要求
Aether 使用 Android 的DexClassLoader 加载 Native Mod 代码。请注意以下约束:
DexClassLoader接受.dex、.apk,或包含classes.dex的 jar/zip 文件。- 普通 JVM
.classjar 不够 — 需对编译输出运行 Android D8 或 R8 以生成 DEX 产物。 - Compose 渲染器必须使用与目标 Aether 构建兼容的 Compose 编译器版本编译。
- 当 Aether 实现类或 Kotlin/Compose 工具链变更时,请重新构建 native mods。这种耦合是有意为之,类似于与版本绑定的 Minecraft mods。
package.json 中的 classpath 格式
在package.json 的 aether.native 下声明 DEX 产物、可选的原生库目录,以及入口类名:
package.json
classpath— 一个或多个相对包根目录的.dex、.apk,或包含 DEX 的 zip/jar 路径。libraryPath— 可选目录,包含.so原生库。entrypoints— 实现AetherNativeMod的完全限定类名。同一包中的多个入口都会被加载。
最小示例
MyNativeMod.kt
Native Mods 在进程启动时加载。安装、更新、移除或更改 Native Mod 后,需重启
Aether 才会生效。