Skip to content

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 在编译时会:

  1. 读取 nativeplugins/*/package.json 获取插件配置
  2. 将原生模块注入编译入口
  3. 在 JS 层通过 uni.requireNativePlugin('pluginName') 暴露原生能力

自定义基座(Custom Base)的作用在于补齐标准基座不包含第三方原生插件这一缺口。制作自定义基座时,HBuilderX 会把 nativeplugins 中的原生代码打入基座 APK/IPA,开发调试阶段才能实际调用这些原生能力。


接入流程的关键步骤

  1. 下载网易云信 NERTC UniApp SDK 包
  2. 在项目根目录创建 nativeplugins/,解压 SDK 到该目录
  3. manifest.json 中声明插件
  4. 在 HBuilderX 中选择"运行 → 制作自定义基座"来打包
  5. 使用自定义基座运行项目

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 的格式。