uni-app调用原生插件必须使用uni.requireNativePlugin,否则无法调用;其返回对象非Promise,未就绪时为null,插件名须与nativePlugins.json中name严格一致,H5和小程序平台返回undefined,Android入口方法必须为main,iOS需严格匹配Objective-C方法签名,打包前须在manifest.json中显式声明路径。

uni-app 调用原生插件必须走 uni.requireNativePlugin
不通过 uni.requireNativePlugin 加载的原生插件,哪怕编译进包里也根本调用不到——这是最常被忽略的前提。uni-app 的 JS 层和原生层是隔离的,require 或 import 原生模块名完全无效。
实操建议:
-
uni.requireNativePlugin返回的是一个对象,不是 Promise,也不支持 await;插件未就绪时返回null,需自行加空值判断 - 插件名必须和
nativePlugins.json中注册的name字段完全一致(大小写敏感) - H5 和小程序平台会直接返回
undefined,不能靠 try/catch 捕获“找不到插件”的错误,得先用uni.getSystemInfoSync().platform判断平台
Android 原生插件的 main 方法签名必须是 public void main(Context context, Map<string object> options, JSCallback success, JSCallback fail)</string>
很多开发者照着 iOS 的写法在 Android 里写 run 或 execute 方法,结果插件加载成功但调用无响应——因为 uni-app 的 Android 容器只认 main 这个固定入口。
常见错误现象:
- 调用插件方法后既不进
success也不进fail回调 - Logcat 里看不到任何插件日志,说明根本没走到 Java 方法体
注意点:
-
options是 JS 传来的参数对象,字段名是字符串,不能直接强转成自定义 Bean -
JSCallback必须调用invoke(),且只允许调用一次;重复调用或传入非 JSON 可序列化对象会导致崩溃 - 所有耗时操作(如网络、文件读写)必须切到子线程,主线程阻塞会卡死整个 WebView
iOS 原生插件的 main 方法必须声明为 - (void)main:(NSDictionary *)options success:(JSCallback)success fail:(JSCallback)fail
Objective-C 方法名、参数顺序、类型缺一不可。写成 execute: 或漏掉 fail 参数,插件能注册成功,但 JS 调用时会静默失败,Xcode 控制台也不会报错。
使用场景提示:
- 如果插件需要访问
UIApplication.sharedApplication,务必在main方法开头加dispatch_async(dispatch_get_main_queue(), ^{ ... }),否则可能因线程上下文不对导致 crash - JS 传来的
options里字符串值可能是NSNull,不是nil,判空要用[value isKindOfClass:[NSNull class]] - 回调中传给 JS 的数据结构必须是 Foundation 原生类型(
NSString/NSNumber/NSArray/NSDictionary),不能传NSDate或自定义 Model
打包前必须在 manifest.json 的 nativePlugins 节点里显式声明插件路径
光把插件文件放进 nativePlugins/ 目录没用。uni-app 构建时不会自动扫描子目录,必须人工配置路径,否则插件不会被打进 apk/ipa。
配置示例(manifest.json 片段):
"nativePlugins": {
"my-pay-plugin": {
"android": "nativePlugins/my-pay-plugin/android",
"ios": "nativePlugins/my-pay-plugin/ios"
}
}
容易踩的坑:
- 路径写成相对路径如
./nativePlugins/...或绝对路径/Users/xxx/...,构建会失败 - Android 路径末尾带斜杠(
android/)或不带(android)都行,但必须指向包含build.gradle和src/的目录 - 同一个插件名不能在不同平台指向同一份代码;iOS 和 Android 插件必须分开存放,即使逻辑相同也不能共用目录
真机调试时插件不生效,第一反应不该是改代码,而是打开生成的 unpackage/dist/build/app-plus/ 目录,确认插件文件是否真的存在、路径是否拼对——90% 的问题出在这一步。










