跨端迁移不靠UI框架:CJMP协议如何统一任务消息与状态同步
去年下半年我们团队做了个决定把内部代号 Grok Bot 的 AI 对话助手从鸿蒙平台完整搬到 iOS 和 Android。当时所有人都以为这就是“把 UI 换一套、API 重新接一遍”的体力活结果排期第三天就发现真正折磨人的根本不是界面而是后台任务、通知通道、文件目录、系统权限这些东西在三个平台上各说各话。折腾到第三周我们引入了一套叫 CJMP 的跨端任务消息协议整个迁移才真正走上正轨。如果你也在做类似的跨端迁移尤其想从单一平台走向双端甚至三端这篇文章应该能让你少走两个月的弯路。1. 为什么一个鸿蒙 Bot 要同时搬到 iOS 和 Android1.1 鸿蒙上跑得挺顺为什么要挪窝先交代背景。Grok Bot 是我们团队做的一个基于大语言模型的智能对话助手核心能力包括多轮对话、定时提醒、轻量工具调用比如帮你查个天气、记个会议、到点提醒你喝水。最初版本基于鸿蒙平台开发用 ArkTS 写界面模型网关单独部署在云端端侧通过 WebSocket 长连接保持在线。鸿蒙版上线后我们收到不少正向反馈但一个很现实的问题摆到桌面上客户和用户并不只用一个生态。很多团队和我们一样面对的是“员工/用户既有鸿蒙手机也有大量 iOS 和 Android 设备”的混合环境。单独押注一个平台意味着大量潜在用户根本没机会接触到这个 Bot。不是鸿蒙不好而是对一个面向大众的助手类产品来说市场覆盖是绕不开的命题。于是目标定下来不放弃鸿蒙版但必须新增 iOS 和 Android 两个端。听起来是个“加法”但实际上我们把整个项目重新拆了一遍底层的技术依赖。1.2 Grok Bot 真正的技术依赖是什么迁移之前团队花了整整两天做一件事把 Grok Bot 的所有依赖全部列出来按“能力类型”归类再逐个标注鸿蒙、iOS、Android 三端的行为差异。我们当时列出的核心依赖大概有这些长连接通信端侧与模型网关之间的 WebSocket 连接负责实时收发对话内容任务调度定时提醒、计划任务的注册、触发、取消通知能力提醒送达时需要弹出系统级通知本地存储聊天记录、用户偏好、任务列表的持久化账号登录绑定用户身份支点多端同步系统权限麦克风权限语音输入、通知权限等包发布与签名三个平台各自的应用签名、审核、上架流程。真正做完这张表我才意识到跨端迁移最痛苦的不是“同一行代码在不同平台跑不通”而是同一个功能概念在三个平台完全是不同的系统机制来实现。比如“定时任务”这件事鸿蒙有自己的任务派对机制Android 得看 Doze 模式和厂商后台限制iOS 又有独立的 Background Task 调度。后面几章细讲。2. 迁移前必须看明白三端系统机制差异到底有多大2.1 后台任务与进程优先级同一个提醒三种命运我们把最难的模块放在前面处理——后台任务。Grok Bot 有一个“定时提醒”功能用户说“明天早上九点提醒我开会”Bot 就要在指定时间把提醒消息推到用户手机上。这个功能在鸿蒙上跑得很正常系统调度、到点触发、通知栏弹出。可换成 Android 和 iOS 以后事情完全变了。平台后台任务机制实际限制注意事项鸿蒙元服务/应用自身任务能力与系统其余应用共存和鸿蒙版本相关AndroidWorkManager、前台 ServiceDoze 模式下延迟执行各厂商 ROM 有“省电策略”必须兼容国内厂商推送和自启动白名单iOSBGTaskScheduler、远程推送后台任务执行时间极短系统不会长期保活进程定时类任务必须依赖服务端推送触发我们自己在真机上测试时同一个“九点提醒”任务Android 某些手机上能准点弹某些手机要等用户点亮屏幕才执行iOS 更极端一个纯后台执行的定时任务几乎不可能准时触发必须要靠远程推送在服务端算好时间下发。这个差异直接否定了“把鸿蒙的任务逻辑平移过去”的思路。后来我们的方案是定时任务不依赖端侧调度全部由服务端定时推送通知端侧只保留一个“本地兜底”逻辑。也就是说端侧任务是最终展示层触发源统一收归服务端。这个改动很大程度是为了绕开平台的进程机制而不是我们懒。2.2 通知通道不是“调个 API”就完事通知功能同样让人头疼。iOS 的通知要走 APNs而且用户安装 App 后第一次打开就要弹窗申请通知权限用户一旦点了“不允许”后续所有提醒都静默丢失。Android 从 8.0 开始引入通知渠道Notification Channel的概念应用必须为每一类通知建一个 channel用户可以在系统设置里单独关掉其中一类。鸿蒙的通知形态又和两者都不一样推送服务也有自己的接入协议。对我们这种“提醒送达率直接决定产品口碑”的场景通知就是生命线。我们见过太多团队从单一平台迁到双端时把通知当成普通模块顺手接一下结果上线后用户投诉“Bot 怎么不提醒了”一看日志才发现推送 token 没上报成功或者用户权限被系统侧默认拒绝了。2.3 文件目录与存储访问路径习惯差异极大另一个容易被新手忽略的坑是文件目录。鸿蒙上应用读写自己的文件目录相对简单iOS 应用只能访问自己的沙盒目录Document、Library、tmp 各有用途Android 从 10 开始强制分区存储应用不能随便读写公共目录甚至访问/storage/emulated/0/Android/data/自己的外部存储目录也会被权限挡住。Grok Bot 需要把聊天记录导出、导入还会把语音输入生成的临时文件存起来。这套逻辑最初是给鸿蒙写的直接搬到 Android 后发现导出文件到公共目录这条路基本走不通必须改用 MediaStore 或 SAF 文档树iOS 上又必须用 FileManager 去定位 Documents 目录。我们最后专门抽象了一个FileStorageAdapter所有文件读写都走这个适配器底层各自实现业务层再也不用关心 Path。3. CJMP 到底帮我解决了什么问题3.1 CJMP 是什么不是 UI 框架是一套消息协议在动手写双端代码之前我们做了选型调研这也是标题里“为什么最后选了 CJMP”的核心。先解释一下 CJMP 是什么CJMPCross-platform Job Messaging Protocol跨端任务消息协议并不是一个 UI 框架也不会帮你渲染任何控件。它定义了一套标准化的任务消息格式、状态流转规则和端侧适配器接口解决的是“业务网关和任意平台端侧之间如何用同一套语言描述任务、上报状态、回传结果”的问题。一句话概括CJMP 把“跨端”这件事从 UI 层下沉到了消息层和任务层。当时我们手里的原型是这样的Grok Bot 的核心逻辑在云端端侧负责采集输入、展示输出、触发任务。端侧和云端之间需要大量消息往来比如用户发起提醒、云端注册任务、到点推送、端侧确认已读。在单平台上这些东西自己定义内部协议就行一旦多端并行每端一套协议后端要对应维护三套格式排查问题也像破案。CJMP 正好抽出了这套统一的“任务—消息—状态”模型。3.2 用任务状态机统一“提交—执行—回执”CJMP 最核心的设计是任务状态机。任何一个端侧或服务端发起的任务都会经历这几个阶段{ msg_type: task.dispatch, task_id: a2f4c19e-7b0e-4a1d-9c2a-ef3b0aa5f6d1, source: server, target: ios, payload: { task: reminder.create, params: { content: 9:00 开会, trigger_at: 2026-05-20T09:00:0008:00 } }, state: pending, timestamp: 2026-05-19T21:30:00Z }这个字段结构我们当时几乎没改动就定了下来msg_type标记消息类型task_id是全链路唯一的任务 IDsource、target标明消息方向payload放具体业务参数state表示当前状态timestamp记录时间。核心是不管什么系统的 Bot只要收发双方都实现了 CJMP任务从“提交”到“成功/失败/取消”的流转就完全一致pending任务被接收入队running端侧开始执行或服务端开始等待调度succeeded任务最终执行成功failed任务执行失败带有失败原因canceled被用户或超时逻辑取消。有人可能会问这不就是一个状态字段吗确实不复杂但真正让协作变顺畅的是两件事状态机是统一强制约定的而不是各端自己想怎么传就怎么传任务 ID 去重和幂等机制保证了同一条提醒不会因为网络重试被创建两次。3.3 端侧适配器协议负责统一差异留在底层CJMP 的另一个关键是适配器接口。协议只约定消息长什么样具体某个端去执行通知、存储、后台任务时由各端的PlatformAdapter实现。我们当时定义了这样一组接口示意interface PlatformAdapter { fun sendNotification(title: String, body: String): Boolean fun saveLocalData(key: String, value: String) fun readLocalData(key: String): String? fun scheduleBackgroundTask(taskId: String, triggerAt: Long) fun getPushToken(): String fun registerTokenRefreshCallback(callback: (String) - Unit) }iOS 和 Android 各自实现这套接口业务层完全不感知底层差异。比如scheduleBackgroundTaskAndroid 端内部用 WorkManager 实现iOS 端内部用 BGTaskScheduler 实现而到底能不能准时执行是适配器实现时要考虑的问题不是业务层每次都要操心的问题。这个设计让我们的迁移方式变成了“加法而不是重构”原生 UI 继续保留站在原地不动核心逻辑往上走一层通过 CJMP 和服务端通信系统能力全部下沉到适配器。每端需要新写的东西就是一个适配器加上若干页面而不是把整个 Bot 的逻辑推倒重来。4. 选型复盘Flutter、RN、KMP 都看过了为什么最后是 CJMP4.1 选型前提我们不缺 UI 框架缺的是逻辑跨端当时团队里有人提议直接用 Flutter 或 React Native 重写整个 App一劳永逸。这个方案我们认真评估了两周最终没有采用。原因不是这些框架不好而是它们解决的不是我们当前最痛的问题。Grok Bot 的 UI 本来就不复杂聊天会话页、任务列表页、设置页广义上就是三个主要页面。原生开发或用 Flutter 重写工作量差别有限。真正复杂的是与云端的长连接、定时任务、通知调度、状态同步这些并不由 UI 框架帮我们跨端。Flutter 再强它的插件生态里后台任务还是得调用原生 APIReact Native 再方便厂商推送适配还是绕不开每个安卓 ROM 的做法。所以我们的真实需求是把业务逻辑中的“任务调度、状态上报、消息回执”用一套统一机制跨端而不是把整个 App 的 UI 统一掉。这是 CJMP 能胜出的最关键前提。4.2 与主流跨端框架的实际对比方案解决的核心问题我们的实际顾虑适配 Grok Bot 的难度FlutterUI 跨端复用UI 不是主要瓶颈包体积增加明显要同时重写 UI风险大React NativeUI 跨端复用 原生模块桥接后台任务、厂商推送仍需原生桥接UI 重写成本高桥接层难维护Kotlin Multiplatform共享业务逻辑iOS 接入有学习成本工具链还在成熟期可用但团队不熟悉 KMPCJMP 协议统一任务消息与状态同步不提供 UI需要各端原生配合适合我们现有的原生团队这里不是要贬低 Flutter 或 RN它们在很多产品里是正确答案。但对一个团队已经拥有原生代码基础、核心逻辑在云端、UI 本身不复杂的 Bot 来说用跨端 UI 框架属于“用大炮打蚊子”还要承担整体重构带来的稳定性风险。CJMP 则不同它只引入一个协议层我们现有代码的迁移成本降到最低。4.3 决策逻辑用加法代替重构选型会最后我们形成了一个共识能加一个协议层解决的问题就不要重构整个应用。迁移计划最终是这样定的服务端接口统一走 CJMP 消息格式iOS 端原 SwiftUI 界面保留新增 CJMP 客户端 SDK 和PlatformAdapterAndroid 端原 Jetpack Compose 界面保留同样接入 CJMP SDK鸿蒙版同步改造接入 CJMP保证三端共享同一套任务语义。实际执行下来整个过程比我们最初排期节省了大概三周。因为不需要重新写任何一端的核心页面也不需要处理 Flutter 和原生插件之间的兼容性问题。每端的开发任务变得很纯粹实现自己的PlatformAdapter把系统能力对齐到协议层的接口语义。5. 迁移落地踩坑清单从 iOS 开发者模式到 Android 分区存储5.1 iOS 开发者模式、证书和真机调试iOS 端碰到的第一个坑是开发者模式。新版本 iOS 在真机调试时手机上必须开启开发者模式否则 Xcode 编译出的应用装到真机上会直接被系统拦截。这个设置藏在“隐私与安全性”里默认是关闭的。当时团队第一次在 iPhone 上调试编译成功但装不上发现问题出在开发者模式没开浪费了一个下午。再一个是证书和 App ID。我们内部测试用的分发方式与正式上架不同测试证书只能装到已注册的设备 UDID 上换一台真机就要重新添加。后来我们统一用企业证书做了内部分发才解决测试团队多台设备的问题。但要注意正式上架 App Store 时必须走常规的发布证书和描述文件流程审核时还要配置好隐私清单。我们因为在隐私清单里漏填了数据收集类型被审核打回了一次。5.2 Android 分区存储路径搬不过去Android 端的代码从鸿蒙移植过来时遇到最隐蔽的坑是分区存储。很多老的 Android 开发习惯里应用会把文件直接写进/storage/emulated/0/Android/data/包名/这样的外部目录用来做导出备份或者日志。Android 10 之后这个目录访问变得极其受限即便应用自己写进去的文件某些场景下也不能直接读取。我们实际碰到的场景是Grok Bot 要把聊天记录导出成文本文件让用户分享出去。最初的代码直接往外部存储写入文件在鸿蒙和旧 Android 上都能跑通在 Android 14 的测试机上就报权限异常。最终方案是改用 MediaStore 的 Downloads 集合来创建导出文件代码改动量不大但必须把原先所有文件路径硬编码全部找出来清理掉。这属于典型的“代码在低版本能跑不代表新版本没问题”。5.3 后台任务的取舍服务端触发 本地兜底前面提过我们最后把定时提醒改成服务端触发加本地兜底。这个方案在实际落地中有个细节iOS 的 BGTaskScheduler 不适合执行“准点提醒”更适合“趁用户凑巧打开 App 时补拉数据”。所以 iOS 端本地兜底逻辑做得很轻只负责在用户打开 App 时检查有没有错过的提醒真正的准点推送完全依赖 APNs。Android 端情况不同WorkManager 可以被系统延迟执行且厂商 ROM 有自己的省电策略。我们额外接入了几个主流厂商的推送 SDK通过厂商通道提高到达率。这又是一个容易忽略的坑不能只接一个 Google 的 FCM 就觉得万事大吉国内 Android 环境必须做厂商推送适配否则离线消息基本送不到。5.4 推送 token 刷新一条消息悄悄丢掉的教训推送 token 的问题也是实际排查了很久才发现。我们最初只在登录时上报一次推送 token逻辑很简单用户登录、拿 token、上报、结束。但实际场景里iOS 的 APNs token 在应用重装、备份恢复、甚至系统更新后都可能变化Android 的厂商 token 也有有效期。如果不做刷新机制就会出现“用户明明装了很多推送 SDK却一条推送都收不到”的灵异情况。CJMP 在这里帮了忙我们把 token 刷新建模成一个独立任务端侧只要检测到 token 变化就通过task.dispatch消息上报到服务端。服务端收到后比对旧 token 并覆盖相当于给推送通道加了“心跳”。上线后推送到达率从最初的 85% 提升到 97% 左右这个提升基本都来自 token 刷新机制。5.5 鸿蒙元服务改造的一个提醒最后说一句鸿蒙这边。我们原本以为鸿蒙版不用动加一个新协议就算完事。实际上为了统一三端消息语义鸿蒙版也要把自己原来那套私有消息格式改成 CJMP。这里最大的一个教训是不要在原来的合成服务上直接“打补丁”而是把元服务的入口重新梳理一遍。合成服务的生命周期和 iOS、Android 的 App/Activity 生命周期差异很大试图用同一个状态机去套原生 App 的逻辑反而会越改越乱。最终我们把鸿蒙版也按“适配器 协议层 页面”拆了一遍问题一下子就清晰了。6. 迁移后的实际数据与团队感受6.1 包体积、启动时间和人日的实测对比迁移完成后我们记录了一些关键数据供同样从单端向双端迁移的团队参考。说明一下这些数字不是实验室环境而是真机测试和内部发布版本统计的结果。指标鸿蒙版Android 版iOS 版安装包体积约 18 MB约 24 MB含厂商推送 SDK约 28 MB冷启动时间约 1.1 秒约 1.3 秒约 1.0 秒通知送达率较高约 97%厂商通道离线包约 98%APNs迁移开发人日基础版本已存在约 15 人日约 12 人日包体积里 Android 和 iOS 偏大主要原因是集成了多家厂商推送 SDK 和 CJMP 客户端的必要依赖。冷启动时间都在可接受范围内因为页面本身不重。迁移开发人日只算了增量部分如果从一开始就用跨端框架重写人日估计要翻倍以上。6.2 稳定性提升的意外收获统一协议后我们意外发现在问题排查上省了很多时间。以前三端各有各的消息格式日志互相看不懂服务端得为每个端写一堆转换逻辑。现在所有端的日志里都能搜同一个task_id从服务端到端侧一条链路拉全排查效率提高得不是一点半点。比如一次用户反馈“提醒没弹”我们直接搜task_id发现消息在服务端显示已下发但端侧适配器sendNotification返回了 false详情一看是用户关掉了通知权限。没有统一协议之前这个排查过程至少要翻两到三套日志系统。6.3 协作方式的变化人人都是协议守护者团队协作方式也因为 CJMP 发生了一点微妙变化。以前 iOS 和 Android 各自为战遇到问题互相甩锅现在所有人围绕同一份协议文档工作任何一端要加字段都得先回到协议层讨论再由各端适配器同步更新。协议评审成为日常开发流程的一部分。一开始有人觉得麻烦后来发现这恰恰是跨端项目减少返工的最有效手段。我自己的体会是跨端迁移最难的部分永远不是写代码而是找到一套让所有端都愿意遵守的“共同语言”。CJMP 对我们来说就是这套语言它没有试图包办一切只做了最该做的那件事把跨平台最复杂的任务调度和消息同步问题收敛到一个足够简单、足够透明的协议里。如果你现在也在折腾类似的迁移别急着选 UI 框架先花一周时间把底层消息协议定清楚这个投入比任何重构都有回报。

相关新闻

C++高并发服务内存分配器选型与性能对比实战

C++高并发服务内存分配器选型与性能对比实战

前一阵调一个 C 后端服务的性能问题,场景很典型:高并发推送网关,每个请求要创建一堆临时小对象,压力一上来,P99 延迟直接从 1.8ms 冲到 12ms。按惯例先用 perf 抓热点,发现 malloc/free 相关符号占了 29% 的…

2026/10/9 5:45:48 阅读更多 →
支持向量机SVM实战全解:从间隔最大化原理到核函数调参与避坑指南

支持向量机SVM实战全解:从间隔最大化原理到核函数调参与避坑指南

简介:一份面向Python学习者的SVM实现学习包,从原理到代码落地,适合想深入理解分类算法内部机制、动手实践模型构建的读者。压缩包体积仅5KB,共6个文件,以.py脚本、.txt测试数据及PyCharm工程配置(.xml/.iml…

2026/10/9 5:45:47 阅读更多 →
开源掌机5W全解析:从GP32到Linux生态的演进与实操指南

开源掌机5W全解析:从GP32到Linux生态的演进与实操指南

1. 开源掌机到底是个什么东西第一次听到“开源掌机”这四个字,很多人的第一反应是:这不就是小时候玩的那种掌上游戏机吗?能有什么区别?我刚开始接触这个圈子的时候也是这么想的,直到自己真正上手折腾了几台设备之后才发…

2026/10/9 5:45:46 阅读更多 →

最新新闻

多模态无监督持续后训练:视觉依赖感知框架解析

多模态无监督持续后训练:视觉依赖感知框架解析

多模态模型的持续更新一直有个很现实的问题:新数据来了,直接继续训练容易忘掉旧能力;不做训练,新场景又用不上。如果数据还没有人工标注,问题会更麻烦。这次我们看的这个框架,名字叫A Visual Dependence-Aw…

2026/10/9 10:33:01 阅读更多 →
SpringBoot+SpringCloud电商源码实战:微服务启动顺序与避坑指南

SpringBoot+SpringCloud电商源码实战:微服务启动顺序与避坑指南

简介:这是一套面向计算机相关专业在校学生与教师的电商系统课程设计/毕业设计源码包,基于Spring Boot与Spring Cloud构建,采用Spring Security、MyBatis、Redis、Docker、Elasticsearch等技术栈,并运用分布式微服务架构&#xff0…

2026/10/9 10:33:01 阅读更多 →
惠普战66拔掉耳机后扬声器无声

惠普战66拔掉耳机后扬声器无声

机型 HP ZHAN 66 Pro A 14 G4 | Windows 10 | 声卡 Realtek ALC236帖主的问题最终还是借助 Cursor 得以修复,下附 Cursor 总结的具体的问题表现、排查过程及结论,供有需要的同仁参考。一、问题描述耳机插上以后,声音正常。耳机拔掉以后&a…

2026/10/9 10:33:01 阅读更多 →
从临时Subagent到持久化AI团队:状态恢复与审计追踪设计

从临时Subagent到持久化AI团队:状态恢复与审计追踪设计

这次我们来看一个很有意思的项目:Show HN: Turn ad-hoc subagents into durable, accountable AI teams。从标题就能看出,它解决的不是“再做一个 Agent”,而是更现实的问题:平时随手创建的临时 Subagent 一到任务结束就丢了&…

2026/10/9 10:33:01 阅读更多 →
RIGOL DS1000系列LabVIEW驱动实战:从RS232/GPIB通信到自动化测试集成

RIGOL DS1000系列LabVIEW驱动实战:从RS232/GPIB通信到自动化测试集成

简介:这份资源面向使用普源DS1000系列示波器、希望借助LabVIEW实现远程控制与数据采集的工程师与测试人员,重点解决RS232串行通信和GPIB总线两种接口下的驱动调用问题。压缩包共54个文件,约570KB,以42个vi虚拟仪器文件为核心&…

2026/10/9 10:33:01 阅读更多 →
图书馆预约系统小程序源码拆解:Java+微信小程序+MySQL三层架构

图书馆预约系统小程序源码拆解:Java+微信小程序+MySQL三层架构

简介:这是一套基于微信小程序的图书馆预约系统毕业设计项目,面向计算机相关专业学生,适用于毕业设计或课程设计场景。系统采用微信小程序开发工具、MySQL数据库与Java的B/S架构实现,完整覆盖管理员、用户、员工三类角色&#xff1…

2026/10/9 10:32:00 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →