Appearance
UniApp 接入网易云信音频通话
这里记录 UniApp 通过 nativeplugins 机制接入原生 SDK(如网易云信 NERTC)的过程。核心难点不在 SDK API 调用本身,而在 原生插件与 UniApp 框架层之间的桥接机制。
nativeplugins 的加载模型
UniApp 的 nativeplugins 目录是原生插件的挂载点。与 npm 包不同,nativeplugins 中的插件包含原生代码(Android 的 .aar/.jar,iOS 的 .framework/.a),在打包时被编译进 App 的原生层。
text
项目根目录/
├── nativeplugins/
│ └── NERTC-SDK/
│ ├── android/ # Android .aar + AndroidManifest.xml
│ ├── ios/ # iOS .framework + module.json
│ └── package.json # 插件元信息
├── unpackage/ # 编译产物
└── manifest.json # 插件声明插件在 manifest.json 中声明后,HBuilderX 在编译时会:
- 读取
nativeplugins/*/package.json获取插件配置 - 将原生模块注入编译入口
- 在 JS 层通过
uni.requireNativePlugin('pluginName')暴露原生能力
自定义基座(Custom Base)的作用在于补齐标准基座不包含第三方原生插件这一缺口。制作自定义基座时,HBuilderX 会把 nativeplugins 中的原生代码打入基座 APK/IPA,开发调试阶段才能实际调用这些原生能力。
接入流程的关键步骤
- 下载网易云信 NERTC UniApp SDK 包
- 在项目根目录创建
nativeplugins/,解压 SDK 到该目录 - 在
manifest.json中声明插件 - 在 HBuilderX 中选择"运行 → 制作自定义基座"来打包
- 使用自定义基座运行项目
JS 层调用:
js
// 获取原生插件实例
const nertc = uni.requireNativePlugin('NERTC-SDK');
// 初始化
nertc.init({
appKey: 'YOUR_APP_KEY',
}, (result) => {
console.log('初始化结果:', result);
});uni.requireNativePlugin 返回的是 JS-Native 桥接层封装出的代理对象。调用代理对象方法时,参数会被序列化后传递到原生层,返回值再通过回调异步回到 JS 层。这个桥接过程通常会引入约 1-5ms 的延迟,但音频通话的数据面走独立媒体通道,不经过 JS Bridge,因此不会成为实时性瓶颈。
常见问题
音频权限:Android 需要 RECORD_AUDIO 权限,iOS 需要在 Info.plist 中添加 NSMicrophoneUsageDescription。权限未授予时,初始化阶段可能不报错,但建立通话后会出现无音频数据的静默失败。排查时可以直接检查 Android 系统权限状态,以及 iOS 侧 AVAudioSession.recordPermission。
自定义基座与标准基座的差异:自定义基座只覆盖开发调试阶段。正式发布仍然需要走“云打包”或“离线打包”,把原生插件打入最终 APK/IPA。即使在自定义基座上测试通过,正式构建阶段仍可能因为 ProGuard 混淆规则缺失导致原生方法调用失败,这一项需要单独核对。
HBuilderX 版本兼容:nativeplugins 的加载机制在不同 HBuilderX 版本间有差异。3.6+ 版本统一了插件加载模型,旧版本项目迁移到新版本时可能需要调整 package.json 的格式。
