Uniapp——安卓与Uniapp数据通信交互
原生向Uniapp通信UniApp 安卓自定义基座Android 原生与 UniApp 双向通信完整方案一、先理解几个核心概念1. globalEvent 是什么2. mUniSDKInstance 是哪里来的3. UniModule 和 UniDestroyableModule 区别二、整体通信架构三、完整代码示例1. 全局保存 UniSDKInstanceUniInstanceHolder.java2. 自定义原生插件NativeBridgeModule.java3. Android Activity 主动发送消息NativeActivity.java4. 注册原生插件dcloud_uniplugins.json5. UniApp 页面使用四、为什么 uni.requireNativePlugin(globalEvent) 不会创建 Module 实例五、Activity 里能不能直接用 mUniSDKInstance六、能不能用 EventBus七、重要注意事项1. 必须先监听再发送2. 必须先绑定 mUniSDKInstance3. globalEvent 只适合当前页面4. 不要强引用 UniSDKInstance5. 关键业务数据建议缓存后主动读取八、推荐使用场景九、最终结论参考文档UniApp 安卓自定义基座Android 原生与 UniApp 双向通信完整方案在 UniApp 安卓自定义基座开发中经常会遇到一个需求Android 原生层拿到数据之后如何传给 UniApp 页面同时 UniApp 页面又如何给 Android 原生发送消息比如这些场景原生登录 SDK 回调登录结果原生支付页面返回支付状态Android Activity 处理完业务后通知 UniAppUniApp 页面主动调用 Android 原生能力原生 SDK 异步回调后需要通知前端页面刷新状态本文整理一套比较完整的双向通信方案Android - UniAppglobalEvent fireGlobalEventCallback UniApp - Androiduni.requireNativePlugin 自定义 UniModule 方法需要注意的是globalEvent不是你自己写的原生插件 Module它只是 UniApp JS 侧的内置事件监听对象。真正能拿到mUniSDKInstance的是你自己写的UniModule或UniDestroyableModule。一、先理解几个核心概念1.globalEvent是什么globalEvent是 UniApp App 端内置的全局事件监听对象。UniApp 页面可以这样监听 Android 原生发来的事件constglobalEventuni.requireNativePlugin(globalEvent)globalEvent.addEventListener(native_event,e{console.log(收到 Android 消息,JSON.stringify(e))})但是它只负责 JS 侧监听不会创建你的 Android Module 实例。也就是说uni.requireNativePlugin(globalEvent)拿到的是 DCloud 内置事件监听对象不是你自己的NativeBridgeModule。2.mUniSDKInstance是哪里来的mUniSDKInstance是UniModule父类提供的当前页面实例。只有你的类继承了UniModule或UniDestroyableModule才可以直接使用mUniSDKInstance例如publicclassNativeBridgeModuleextendsUniModule{UniJSMethod(uiThreadtrue)publicvoidsendEvent(){mUniSDKInstance.fireGlobalEventCallback(native_event,params);}}如果代码写在下面这些地方是没有mUniSDKInstance的ActivityApplicationServiceBroadcastReceiver普通工具类SDK回调类这也是很多人找不到mUniSDKInstance的原因。3.UniModule和UniDestroyableModule区别类作用适合场景UniModule普通原生 Module一次性调用、获取数据、打开页面UniDestroyableModule带销毁生命周期的 ModuleEventBus 注册、监听器、定位、蓝牙、SDK 回调等需要释放的场景如果只是简单调用getToken(callback)用UniModule就可以。如果你有EventBus.register(this)BroadcastReceiver注册Handler延迟任务SDK监听回调Dialog/Popup持有Activity建议使用UniDestroyableModule因为它可以在destroy()中释放资源。二、整体通信架构推荐结构如下UniApp 页面 | | uni.requireNativePlugin(NativeBridge) v NativeBridgeModule | | 保存 mUniSDKInstance v UniInstanceHolder | | Activity / SDK 回调调用 fireEvent v mUniSDKInstance.fireGlobalEventCallback(...) | v UniApp globalEvent.addEventListener(...)双向通信关系UniApp - Android nativeBridge.sendMessageToAndroid(params, callback) Android - UniApp mUniSDKInstance.fireGlobalEventCallback(native_event, data) Android - UniApp 页面监听 globalEvent.addEventListener(native_event, callback)三、完整代码示例下面示例实现两个方向UniApp 主动给 Android 发送消息Android Activity 主动给 UniApp 页面发送消息1. 全局保存 UniSDKInstanceUniInstanceHolder.java不要直接用publicstaticUniSDKInstanceinstance;因为UniSDKInstance绑定的是当前页面实例直接静态强引用容易导致页面泄漏、旧页面收到事件、事件发错页面。建议用WeakReferencepackagecom.xxx.uniplugin;importandroid.os.Handler;importandroid.os.Looper;importjava.lang.ref.WeakReference;importjava.util.Map;importio.dcloud.feature.uniapp.UniSDKInstance;publicclassUniInstanceHolder{privatestaticWeakReferenceUniSDKInstanceinstanceRef;publicstaticvoidbind(UniSDKInstanceinstance){instanceRefnewWeakReference(instance);}publicstaticvoidclear(UniSDKInstanceinstance){if(instanceRef!nullinstanceRef.get()instance){instanceRef.clear();instanceRefnull;}}publicstaticvoidfireEvent(StringeventName,MapString,Objectdata){if(instanceRefnull)return;UniSDKInstanceinstanceinstanceRef.get();if(instancenull)return;newHandler(Looper.getMainLooper()).post(()-{instance.fireGlobalEventCallback(eventName,data);});}}2. 自定义原生插件NativeBridgeModule.java这个 Module 负责绑定当前页面的mUniSDKInstance接收 UniApp 发来的消息回调结果给 UniApp测试 Android 主动发送事件给 UniApp页面销毁时清理实例packagecom.xxx.uniplugin;importcom.alibaba.fastjson.JSONObject;importjava.util.HashMap;importjava.util.Map;importio.dcloud.feature.uniapp.annotation.UniJSMethod;importio.dcloud.feature.uniapp.bridge.UniJSCallback;importio.dcloud.feature.uniapp.common.UniDestroyableModule;publicclassNativeBridgeModuleextendsUniDestroyableModule{UniJSMethod(uiThreadtrue)publicvoidbindUniInstance(){UniInstanceHolder.bind(mUniSDKInstance);}UniJSMethod(uiThreadtrue)publicvoidunbindUniInstance(){UniInstanceHolder.clear(mUniSDKInstance);}/** * UniApp 主动给 Android 发送消息 */UniJSMethod(uiThreadtrue)publicvoidsendMessageToAndroid(JSONObjectparams,UniJSCallbackcallback){Stringtypeparams.getString(type);Stringcontentparams.getString(content);android.util.Log.e(NativeBridge,type type);android.util.Log.e(NativeBridge,content content);if(callback!null){JSONObjectresultnewJSONObject();result.put(code,0);result.put(msg,Android 已收到 UniApp 消息);result.put(receiveType,type);result.put(receiveContent,content);callback.invoke(result);}}/** * Android 主动发送事件给 UniApp */UniJSMethod(uiThreadtrue)publicvoidtestSendEventToUniApp(){MapString,ObjectdatanewHashMap();data.put(type,android_event);data.put(msg,这是 Android 主动发送给 UniApp 的消息);UniInstanceHolder.fireEvent(native_event,data);}Overridepublicvoiddestroy(){UniInstanceHolder.clear(mUniSDKInstance);super.destroy();}}3. Android Activity 主动发送消息NativeActivity.java如果你是在 Activity 中拿到了数据比如登录结果、支付结果、页面选择结果可以这样通知 UniApppackagecom.xxx.uniplugin;importandroid.app.Activity;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;importjava.util.HashMap;importjava.util.Map;publicclassNativeActivityextendsActivity{OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);ButtonbuttonnewButton(this);button.setText(发送数据给 UniApp);button.setOnClickListener(newView.OnClickListener(){OverridepublicvoidonClick(Viewview){sendDataToUniApp();}});setContentView(button);}privatevoidsendDataToUniApp(){MapString,ObjectdatanewHashMap();data.put(type,activity_result);data.put(token,abc123);data.put(userId,10001);UniInstanceHolder.fireEvent(native_event,data);}}4. 注册原生插件dcloud_uniplugins.json注意name要和前端的uni.requireNativePlugin(NativeBridge)保持一致。{nativePlugins:[{plugins:[{type:module,name:NativeBridge,class:com.xxx.uniplugin.NativeBridgeModule}]}]}如果是自定义基座需要重新打包自定义基座。5. UniApp 页面使用template view classpage button clicksendToAndroidUniApp 发消息给 Android/button button clickandroidSendToUniApp测试 Android 发消息给 UniApp/button view classtitle结果/view text{{ result }}/text /view /template script const globalEvent uni.requireNativePlugin(globalEvent) const nativeBridge uni.requireNativePlugin(NativeBridge) export default { data() { return { result: } }, onLoad() { // Android - UniApp globalEvent.addEventListener(native_event, e { console.log(收到 Android 主动消息, JSON.stringify(e)) this.result JSON.stringify(e) }) // 绑定当前页面对应的 mUniSDKInstance nativeBridge.bindUniInstance() }, onUnload() { nativeBridge.unbindUniInstance() }, methods: { // UniApp - Android sendToAndroid() { nativeBridge.sendMessageToAndroid( { type: user_click, content: 用户点击了按钮 }, res { console.log(Android 返回, JSON.stringify(res)) this.result JSON.stringify(res) } ) }, // 测试 Android - UniApp androidSendToUniApp() { nativeBridge.testSendEventToUniApp() } } } /script四、为什么uni.requireNativePlugin(globalEvent)不会创建 Module 实例因为globalEvent是 DCloud 内置事件监听模块不是你自己注册的插件。下面这句constglobalEventuni.requireNativePlugin(globalEvent)只是在 JS 侧拿到事件监听对象用来globalEvent.addEventListener(native_event,callback)它不会创建你的NativeBridgeModule真正创建你自定义 Module 的是constnativeBridgeuni.requireNativePlugin(NativeBridge)前提是你已经在dcloud_uniplugins.json中注册{type:module,name:NativeBridge,class:com.xxx.uniplugin.NativeBridgeModule}五、Activity 里能不能直接用mUniSDKInstance不能直接用。因为 Activity 并不继承UniModule所以它没有mUniSDKInstance。错误理解publicclassNativeActivityextendsActivity{// 这里没有 mUniSDKInstance}正确做法UniModule 拿到 mUniSDKInstance ↓ 保存到 UniInstanceHolder ↓ Activity 通过 UniInstanceHolder.fireEvent(...) ↓ UniApp 通过 globalEvent 收到六、能不能用 EventBus可以。但 EventBus 只能解决 Android 原生层内部通信不能直接把数据发到 UniApp JS。正确结构应该是Activity / SDK 回调 ↓ EventBus.post(...) ↓ NativeBridgeModule 接收事件 ↓ mUniSDKInstance.fireGlobalEventCallback(...) ↓ UniApp globalEvent 收到也就是说EventBus 是 Android 内部消息通道globalEvent才是 Android 通知 UniApp 的通道mUniSDKInstance仍然是最终发送事件的关键如果业务是登录结果、支付结果这种“不允许丢”的数据也可以用postSticky或者更稳一点原生先缓存UniApp 页面加载后主动读取。七、重要注意事项1. 必须先监听再发送UniApp 页面必须先执行globalEvent.addEventListener(native_event,callback)然后 Android 再发送fireGlobalEventCallback(native_event,data)如果 Android 发送太早事件会丢。2. 必须先绑定mUniSDKInstance页面加载后要调用nativeBridge.bindUniInstance()否则 Activity 通过UniInstanceHolder.fireEvent(...)时没有可用的页面实例。3.globalEvent只适合当前页面globalEvent是通过当前页面的UniSDKInstance发送事件所以更适合当前页面接收。如果你的 App 有多个页面或者页面切换频繁需要特别注意当前保存的是不是最新页面实例旧页面销毁时有没有清理事件是否可能发给错误页面4. 不要强引用UniSDKInstance不推荐publicstaticUniSDKInstanceinstance;推荐privatestaticWeakReferenceUniSDKInstanceinstanceRef;并在destroy()中清理UniInstanceHolder.clear(mUniSDKInstance);5. 关键业务数据建议缓存后主动读取如果是下面这些数据登录结果支付结果SDK 初始化结果广告归因结果启动参数不建议完全依赖globalEvent。更稳的方式是Android 先缓存数据 ↓ UniApp 页面 onLoad / onShow ↓ 主动调用 nativeBridge.getPendingData(...) ↓ Android 通过 callback 返回数据因为globalEvent有监听时机问题一旦页面没有准备好事件就可能丢。八、推荐使用场景场景推荐方案UniApp 主动调用原生能力NativeBridgeModule UniJSCallbackAndroid 主动通知当前页面globalEvent fireGlobalEventCallbackActivity 给 UniApp 发实时事件UniInstanceHolder globalEventService / SDK 回调通知页面EventBus NativeBridgeModule globalEvent登录、支付等不能丢的数据原生缓存 UniApp 主动读取长时间监听定位、蓝牙、传感器UniDestroyableModule管理生命周期九、最终结论UniApp 安卓自定义基座里原生与 UniApp 双向通信可以这样理解UniApp - Android 调用自定义 NativeBridgeModule 方法 Android - UniApp 通过 mUniSDKInstance.fireGlobalEventCallback 发送 globalEvent Activity 里没有 mUniSDKInstance 需要通过 UniModule 绑定后间接使用最推荐的整体方案是UniApp 页面 addEventListener ↓ UniApp 调 bindUniInstance ↓ UniModule 保存当前 mUniSDKInstance ↓ Activity / SDK 回调通过 Holder 或 EventBus 通知 ↓ UniModule / Holder 调 fireGlobalEventCallback ↓ UniApp 收到事件如果只是实时通知这套方案可以使用。如果是关键业务结果比如登录、支付、归因建议增加一层缓存让 UniApp 主动读取避免事件丢失。参考文档uni.requireNativePlugin 官方文档DCloud Android 原生插件开发文档DCloud UniMP Android 扩展开发文档

相关新闻

GitHub Desktop中文汉化终极指南:3分钟实现完整界面本地化

GitHub Desktop中文汉化终极指南:3分钟实现完整界面本地化

GitHub Desktop中文汉化终极指南:3分钟实现完整界面本地化 【免费下载链接】GitHubDesktop2Chinese GithubDesktop语言本地化(汉化)工具 【GitHub桌面客户端中文汉化】 项目地址: https://gitcode.com/gh_mirrors/gi/GitHubDesktop2Chinese 你是否在使用GitH…

2026/7/8 3:51:33阅读更多 →
ARM64 汇编逆向分析:从IDA Pro静态分析到Frida动态Hook实战

ARM64 汇编逆向分析:从IDA Pro静态分析到Frida动态Hook实战

ARM64 逆向工程实战:从静态分析到动态 Hook 的完整技术链移动安全领域的技术迭代速度令人惊叹,而 ARM64 架构作为现代移动设备的主流指令集,其逆向分析技术已成为安全研究人员的必修课。本文将带你深入 ARM64 逆向的核心环节,从 I…

2026/7/8 3:46:32阅读更多 →
Multi-Agent协作开发:重构中大型项目研发流程的工程实践

Multi-Agent协作开发:重构中大型项目研发流程的工程实践

1. 这不是“多个机器人聊天”,而是重构开发流程的协作范式Multi-Agent 协作开发,这个词最近在技术圈被反复提起,但很多人一听到“Agent”,下意识就想到“AI助手”“自动写代码”“替代程序员”。这种理解偏差,恰恰是踩…

2026/7/8 3:46:32阅读更多 →
Windows 11任务栏歌词终极指南:让音乐无缝融入你的工作流

Windows 11任务栏歌词终极指南:让音乐无缝融入你的工作流

Windows 11任务栏歌词终极指南:让音乐无缝融入你的工作流 【免费下载链接】Taskbar-Lyrics BetterNCM插件,在任务栏上嵌入歌词,目前仅建议Windows 11 项目地址: https://gitcode.com/gh_mirrors/ta/Taskbar-Lyrics 还在为听歌时需要频…

2026/7/8 8:02:19阅读更多 →
Windows HEIC缩略图终极方案:让iPhone照片在资源管理器中完美显示

Windows HEIC缩略图终极方案:让iPhone照片在资源管理器中完美显示

Windows HEIC缩略图终极方案:让iPhone照片在资源管理器中完美显示 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC/HEIF files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 还…

2026/7/8 8:02:19阅读更多 →
Diablo Edit2深度解析:揭秘暗黑破坏神2存档编辑器的技术实现与实战应用

Diablo Edit2深度解析:揭秘暗黑破坏神2存档编辑器的技术实现与实战应用

Diablo Edit2深度解析:揭秘暗黑破坏神2存档编辑器的技术实现与实战应用 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 在暗黑破坏神2的二十年游戏历史中,玩家们一直寻求着…

2026/7/8 8:02:19阅读更多 →
不用花钱的 AI 换脸方案 – VisoMaster-Fusion 批量视频图片换脸

不用花钱的 AI 换脸方案 – VisoMaster-Fusion 批量视频图片换脸

今天发点适合做视频/图片换脸的东西。 平时让想弄点恶搞视频或者图片时,换脸用 PS 老是 P 的不好,用 AI 吧又有点贵。 我终于在GitHub上找到一个好东西,叫 VisoMaster-Fusion,本地就能完成视频或者图片的换脸功能,我…

2026/7/8 8:02:19阅读更多 →
软件系统安全设计:从 OWASP Top 10 到 4 层防护体系落地

软件系统安全设计:从 OWASP Top 10 到 4 层防护体系落地

软件系统安全设计:从 OWASP Top 10 到 4 层防护体系落地在数字化浪潮席卷各行各业的今天,软件系统已成为企业运营的核心支柱。然而,随着技术复杂度的提升和攻击手段的演进,系统安全已从"可有可无"的附加项转变为"生…

2026/7/8 8:02:19阅读更多 →
怎样高效使用D3KeyHelper:智能自动化助手实战指南

怎样高效使用D3KeyHelper:智能自动化助手实战指南

怎样高效使用D3KeyHelper:智能自动化助手实战指南 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏神3中繁琐的重复操作而烦…

2026/7/8 7:57:19阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/8 5:12:14阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/8 7:00:12阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/8 2:26:06阅读更多 →
作为一个给团队打绩效的人,我想说几句

作为一个给团队打绩效的人,我想说几句

我每半年都会给团队成员打绩效,也会参与和 CTO 的绩效校准,所以从管理者的视角,说说这件事 首先,我先把结论告诉你:接受结果,但一定要把原因问清楚。 因为当绩效公布到你这里的时候,结果基本已…

2026/7/8 0:01:17阅读更多 →
A股股指期货:全维度解析(多表格结构化完整版)

A股股指期货:全维度解析(多表格结构化完整版)

一、基础定义与核心本质股指期货全称股票价格指数期货,是中国金融期货交易所(中金所)上市的标准化金融期货合约,交易标的为 A 股大盘指数,约定未来特定时间按约定价格现金交割指数涨跌差价,不交割一篮子股票…

2026/7/8 0:01:17阅读更多 →
iOS越狱新手指南:从困惑到掌控,3天解锁iPhone无限潜能的真实故事

iOS越狱新手指南:从困惑到掌控,3天解锁iPhone无限潜能的真实故事

iOS越狱新手指南:从困惑到掌控,3天解锁iPhone无限潜能的真实故事 【免费下载链接】Jailbreak iOS 26.4 - 26, 17 - 17.7.5 & iOS 18 - 18.7.3 Jailbreak Tools, Cydia/Sileo/Zebra Tweaks & Jailbreak News Updates || AI Jailbreak Finder &…

2026/7/8 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/8 6:59:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/7 5:11:21阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/7 5:11:21阅读更多 →