AI时代的应用开发神器:cj-tauri 已支持鸿蒙 PC,第一次的踩坑记录
cj-tauri 已支持鸿蒙 PC啦记录一下第一次的踩坑记录。第一次把 cj-tauri 应用跑进鸿蒙 PC白屏三轮最后是一条 llvm-nm 定的案。以后造些软件工具还用啥原生啊五分钟造一个应用这开发速度将原生比下去。因为AI时代AI最擅长的语料还是web从此开发鸿蒙应用又多了一个选择。而且是开发速度最快的那条路。测试设备华为 MateBook ProHAD-W32、HarmonyOS 7.0.0.107、API 26、aarch64屏幕 3120×2080 px、密度 190%。工具链是 DevEco Studio 6.1 自带的仓颉插件hdc 串号3QC0124B20000048。cj-tauri框架cj-tauri同一个页面在 WindowsWebView2和LinuxWebKitGTK上已经跑了大半年。下面这轮的完整证据链留在docs/鸿蒙ArkWeb接入踩坑.md这篇只讲我自己的那份「本来以为」是怎么被推翻的。cj-tauri是什么cj-tauri · 仓颉版 Tauri。用华为仓颉语言实现的桌面应用混合开发框架 —— 仓颉静态编译后端 系统 WebView 前端产物不带 Chromium、几 MB 级。官网地址https://yangyongzhen.github.io/cj-tauri/项目地址https://atomgit.com/qq8864/cj-tauri起因我以为最难的会是 ArkWeb仓库里那个音乐播放器示例Windows 和 Linux 都是三栏布局、能放歌、歌词跟着走。我想把它搬到这台鸿蒙笔记本上心里排的难度顺序是ArkWeb 的Web组件怎么用 仓颉怎么跟 JS 双向通信 工程怎么编成 hap。C 桥、运行时、包管理这些「已经有了」的东西我根本没排进风险清单。结果正好反过来了ArkWeb 那部分是最顺的真正让我白走一晚上的是一条符号表。第一轮白屏应用启动即退hilog 里连一行onCreate都没有第一次装上去点图标屏幕黑一下就没了。我先跑的是 hdc 的 hilog看到的是这个exit with signal:11仓颉运行时自己的CANGJIE-RUNTIME那几行照常打印但我自己的AbilityStage.onCreate一行都没有。于是我开始往「生命周期」上想那晚白走了三轮以为 ability 生命周期卡死了。在onCreate里加日志日志没出来——看起来像「根本没进生命周期」其实是那行日志所在的模块加载期就已经死了。以为运行时模块初始化死锁。鸿蒙侧的仓颉运行时会把模块的初始化链拉一遍我猜是静态包硬链进动态根包导致init卡住。改了几次依赖写法结论没变。以为 stdx 重复链接。把 stdx 的引入方式来回换一样。三条判断的共同毛病是我一直在看运行期日志而这次失败发生在「日志能力本身可能不在了」的地方。判据不要看日志看符号后来我把排查顺序倒过来先问一句「这个模块里有没有解析不了的符号」一条命令出结果llvm-nm-D--undefined-only entry/build/default/intermediates/libs/default/arm64-v8a/libentry.so|grepcj_bridge必须是 0 行。当时不是 0 行。根因很简单但很反直觉src/log_bridge.cj是故意不写When的——桌面两个平台导出同名符号、实现只有native/core/bridge_core.c一份所以这文件打一开始就没打算做平台分叉。可鸿蒙侧没有 C 桥产物那三个foreign func在模块里是U模块加载期直接 SIGSEGV。地址看着像野指针而不是空指针这也是我当时没往「符号缺失」上想的原因。修法没有桥就如实降级别假装成功给 FFI 声明与薄包装加同一口径的平台门禁再给无桥平台写一份如实的降级When[env!ohos]foreign funccj_bridge_set_log_file(path:CString):Int32// 无桥平台不写文件日志但要留一行 stderr别静默When[envohos]funcenableLogFile(path:String):Bool{eprintln([cj-tauri] file logging is not available on this platform)returnfalse}两块必须同时改只给foreign func加When、不给调用方加编译期直接报未声明反过来只改调用方链接期还是那个U。改完同一条14 llvm-nm ... | grep cj_bridge变成 0 行MyAbilityStage onCreated重新出现在 hilog 里。顺带记住两条判断口径它们比任何日志都直接鸿蒙的os取值就是Linuxarch也不能用桌面 aarch64 Linux 一样是 aarch64。平台判据只认envaarch64-linux-ohos→ohos桌面 →gnu。所以框架里一律写When[env ohos]/When[env ! ohos]。同族风险面src/clipboard_bridge.cj以及任何「谁调用谁包内」的核心 FFI。新增之前先问一句「这个平台有桥吗」。第二轮白屏窗口起来了页面纯白符号修完应用能起来了、窗口也在但页面全白。这次 hilog 里有意思了BindWebTagToWebInstance webTag:arkweb:0Web组件确实建过但page begin/page end一条都没有。真因是声明式 UI 的一个求值时机问题Component的build()是一次性求值而宿主把内联页面落盘后的file://地址只存在宿主对象上组件自己那个字段初值是空串。于是首帧if (pageUrl.size 0)不成立 →不建Web→onPageBegin永远不来 → 而我原设计的「地址同步点」恰好就写在onPageBegin里。死锁页面永远白屏。修法是把同步点前移到aboutToAppear()首次build()之前跑一次StatevarpageUrl:String// 注意State 不允许带 private / public带了直接编译失败protectedfuncaboutToAppear():Unit{pageUrlhost.currentUrl()// 宿主落盘后的 file:///.../cj-tauri-main.htmlHilog.info(1,CjTauri,host pageUrl labelmain url${pageUrl})}State只在组件自己赋值时触发重绘宿主在别的线程改它自己的字段组件永远读到旧值——这条我踩了一次才服。第三轮页面出来了命令没反应到这一步页面渲染正常但点system:version一直显示-promise 既不 resolve 也不 reject。先在页面里绕过桥做三个探针把嫌疑排掉typeofwindow.__CJ_TAURI_HOST__// objecttypeofwindow.__CJ_TAURI_HOST__.post// functiontry{window.__CJ_TAURI_HOST__.post({...})}// 同步调用成功三项都正常说明注入通道好、post也好。那问题只能在「回投」这一侧。桌面版用的是「页面定时poll()取回待执行脚本」的泵鸿蒙侧我照搬了结果是poll - null。隔离实验很干脆把funcList里的poll换成无条件返回固定串的实现不看框架、只改应用侧那一行——funcList:[{_poll-probe}]// 页面拿到的仍然是 null仓颉侧funcList的返回值根本回不到 JS。参数能进去、methodList枚举顺序也对、方法都调得到就是返回值恒为null。所以「页面拉、原生答」这种同步取数模型在鸿蒙侧不成立。改成反过来由原生推链路就通了页面setInterval发一条{type:pull}心跳 → 宿主识别后直接 return、不进 IPC 分发 → 应用侧 proxy 回调本来就在 UI 线程取队列里的待执行脚本用controller.runJavaScript推出去。runJavaScript本身是通的日志里有runJavaScript ok。两条便宜的教训eprintln在设备上完全不可见。框架里 stderr 是主要的诊断通道在鸿蒙上等于没有——诊断一律写 hilog。一次性hilog -x会把启动瞬间那几行滚掉。hilog -r清缓冲 → 启动 → 等十几秒 →hilog -x 中间系统日志能刷三千多行我们那 510 行直接被挤出环形缓冲。判据很怪ps里进程活着但Cangjietag 计数是 0。取证一律流式先起hdc shell hilog f再启动应用跑完再 grep 文件。现在正常启动的标记链跑通之后我把这条链当成验收标准八行缺哪行就知道断在哪MyAbilityStage onCreated host registered after 0 polls labelmain host pageUrl labelmain urlfile:///data/storage/el2/base/haps/entry/files/cj-tauri-main.html page begin labelmain runJavaScript ok结语回头看这轮最贵的一课不是「ArkWeb 怎么用」而是排错顺序当失败可能发生在「诊断能力本身失效」的位置时无桥平台的 FFI、加载期崩溃、日志被滚掉先取一条不问运行期的证据——这次是符号表比任何一行日志都快。下一篇写窗口尺寸我为了让窗口「正常点」连续两版都把系统给的合适默认值改坏了。最终让cj-tauri支持鸿蒙PC挺简单的在arkui侧也是使用的纯仓颉的代码。从此使用web技术开发鸿蒙应用又多了一个选择。以后造些软件工具还用啥原生啊五分钟造一个应用这开发速度将原生比下去因为AI时代AI最擅长的语料还是web。