Rust + Tauri调用鸿蒙系统原生API,打通桥接实战经验总结

发布时间:2026/8/23 19:55:38
Rust + Tauri调用鸿蒙系统原生API,打通桥接实战经验总结 真不容易啊,网上这方面资料很少,探索尝试了很久终于打通了调用鸿蒙原生API的方法。这有什么用?使用Tauri做跨端APP是个不错的技术方案,可以一次可以跨N端。但是呢肯定避免不了依赖和使用系统的原生API来扩展能力。当前Tauri在android和ios端,官方都有插件支持。但鸿蒙还不支持,有待探索。目标读者:正在(或即将)把 Tauri 应用往鸿蒙(HarmonyOS)上搬、想调用系统原生能力(相册、分享、通知、剪贴板……)的开发者。本文是一篇实战记录,不是官方文档复述。所有结论都经过真机验证和源码核实, 证据在文末。踩过的坑都在,能让你少走两天弯路。更多交流学习,欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper猫哥的博客:https://blog.csdn.net/qq88640. 先说结论Tauri v2 在鸿蒙上调用原生 API,绕不开一件事:让 Rust 代码在"主线程"上执行。不是"最好在主线程",是必须。因为openharmony-ability的get_main_thread_env()是一个thread_local,只有主线程能拿到Env,而拿到Env才能调 ArkTS 侧的函数。tauri 的同步命令却跑在IPC 线程——两头对不上,就是看到的main thread env not ready的全部原因。解法(本仓库验证通过):AppHandle::run_on_main_thread+ channel,把调用投递到主线程,同步等结果。就这么简单,但想明白这行代码,花了些时间探索。1. 背景:我们要做什么应用(习惯树)有一个"里程碑卡片":庆祝动画画一张词句落款卡片,用户点"保存卡片"把它存到相册/下载目录,用户自己能看见。习惯树开源地址:https://atomgit.com/qq8864/habit-tree桌面端简单:Rust 写文件到下载目录。鸿蒙端不行——应用沙箱用户看不到,媒体库直写要敏感权限(READ_MEDIA 之类,上架审核麻烦)。正路是PhotoViewPicker:系统弹窗让用户选保存位置,免权限,用户确认后返回 uri,写入即可。完美符合需求。但 PhotoViewPicker 是ArkTS 的 API(方舟运行时),前端 JS(WebView 引擎)和 Rust 都摸不到。所以要搭一条Rust → ArkTS的桥:前端 JS ──invoke──▶ Rust 命令 ──NAPI──▶ ArkTS 全局函数 ──▶ PhotoViewPicker这条链,每一步都有坑。逐个说。2. 桥的骨架:全局分发器ArkTS 侧(EntryAbility)挂一个全局函数,作为统一入口:// EntryAbility.etsinterfaceDispatchPayload{base64:string;filename:string;}interfaceDispatchMsg{plugin:string;cmd:string;payload:DispatchPayload;}// onCreate 里:(globalThisasESObject).__ohos_dispatch=(msg:string):string={try{constparsed=JSON.parse(msg)asDispatchMsg;if(parsed.plugin==='grove'parsed.cmd==='save_card'){this.saveCardToGallery(parsed.payload.base64,parsed.payload.filename);returnJSON.stringify({ok:true,note:'picker opened'});}returnJSON.stringify({ok:false,err:'unknown cmd'});}catch(e){returnJSON.stringify({ok:false,err