真不容易啊,网上这方面资料很少,探索尝试了很久终于打通了调用鸿蒙原生API的方法。这有什么用?使用Tauri做跨端APP是个不错的技术方案,可以一次可以跨N端。但是呢肯定避免不了依赖和使用系统的原生API来扩展能力。当前Tauri在android和ios端,官方都有插件支持。但鸿蒙还不支持,有待探索。
目标读者:
正在(或即将)把 Tauri 应用往鸿蒙(HarmonyOS)上搬、想调用系统原生能力(相册、分享、通知、剪贴板……)的开发者。
本文是一篇实战记录,不是官方文档复述。所有结论都经过真机验证和源码核实, 证据在文末。踩过的坑都在,能让你少走两天弯路。
更多交流学习,欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
猫哥的博客:https://blog.csdn.net/qq8864

0. 先说结论
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.ets
interface DispatchPayload {
base64: string; filename: string; }
interface DispatchMsg {
plugin: string; cmd: string; payload: DispatchPayload; }
// onCreate 里:
(globalThis as ESObject).__ohos_dispatch = (msg: string): string => {
try {
const parsed = JSON.parse(msg) as DispatchMsg;
if (parsed.plugin === 'grove' && parsed.cmd === 'save_card') {
this.saveCardToGallery(parsed.payload.base64, parsed.payload.filename);
return JSON.stringify({
ok: true, note: 'picker opened' });
}
return JSON.stringify({
ok: false, err: 'unknown cmd' });
} catch (e) {
return JSON.stringify({
ok: false, err

292

被折叠的 条评论
为什么被折叠?



