HarmonyOS开发中Ability生命周期与Want跳转实战指南

HarmonyOS开发中,Ability生命周期和Want(也就是大家常说的Intent)这两块内容,是每个新手进团队后最先接触、也最容易看轻的部分。很多人一开始觉得“这跟Android的Activity不是一回事儿嘛”,结果真到自己上手做页面跳转、做状态管理的时候,各种生命周期回调顺序不对、数据对不上、白屏闪退的问题全冒出来了。这篇文章我把自己这几年在HarmonyOS应用开发里对Ability和Want的理解、踩过的坑、沉淀下来的套路,一次性整理清楚,希望能给正在入门或者已经写了一阵子HarmonyOS代码的朋友一些实质性的参考。

1. 先搞清楚Ability和Want在整个体系里的位置

1.1 为什么HarmonyOS要设计一套自己的组件模型

HarmonyOS作为一个面向多设备、多形态的操作系统,从设计之初就面临一个核心问题:手机上的应用怎么跑到平板、手表、车机、智慧屏上,还尽量少改代码。Android里的Activity依赖的是窗口和触摸事件模型,搬到手表、音箱这类设备上,很多概念是别扭的。HarmonyOS于是抽象出了Ability这个概念——它的定位是一个能力单元,你把自己程序能干什么拆成若干个能力块,每个Ability承载一块独立的功能。

和Ability配套的就是Want。一条Want可以理解为一个“任务描述单”,上面写着“我要打开哪个应用、哪个能力,要不要带上特定参数”。HarmonyOS的组件间跳转、服务拉起、数据流转,底层都靠Want这张单子流转消息。所以你和队友做接口对接的时候,真正聊的其实是“我是用它来开页面,还是为了起后台任务,还是为了拿数据”,想清楚这一点,后续的API全都不难选。

1.2 三种Ability形态各司其职

HarmonyOS把Ability按用途拆成了三类:

  • Page Ability:带用户界面的,负责展示和交互,一个页面通常就是一个Page Ability。
  • Service Ability:不带界面,常驻后台执行任务,可以提供接口给前台调用。
  • Data Ability:专门做数据管理,为其他应用提供统一的数据读写入口,相当于一个数据仓库的接待员。

这套设计对业务开发的意义其实很实在。以前你在Android里写后台任务,要考虑Service怎么保活、进程怎么处理,现在HarmonyOS直接把Service Ability变成了一种系统级的任务单元,系统回收有统一的策略;数据存储也给你单独划出Data Ability,不再散落在各个Activity里难管理。理解了这三类形态,才能理解后面说的生命周期为什么每一类都不一样。

2. Page Ability生命周期全解析

2.1 六个核心回调放在一条时间线上看

Page Ability的生命周期,用一句话概括就是:从创建到结束,系统会在不同时机回调你注册好的方法。经典FA模型下主要有onStart、onActive、onInactive、onBackground、onForeground、onStop这六个。

这里我画了一张时序关系,按实际运行顺序排开是这样的:

回调触发时机状态含义
onStartAbility启动时,页面DOM还没完成加载做初始化、读配置
onActive页面进入前台并且可以和用户交互开启动画、恢复交互操作
onInactive页面可见但在失去焦点或被遮挡保存草稿、暂停耗时操作
onBackground页面彻底不可见,退到后台释放资源、记录停留时间
onForeground页面从后台重新回到前台刷新数据、恢复前台需要的资源
onStop页面销毁前清理监听、释放大对象

我见过很多刚从Web开发转过来的同事,第一反应是“是不是写一个onStart就行”,其实真不是这样。onStart只代表这个Ability的壳被创建了,里面的组件还没加载完,你要是这会儿就在代码里去获取某个子组件的宽高、去触发绘制,大概率拿不到预期结果。有渲染相关操作的,你得放到onActive之后做。这一条建议直接背下来,能省不少无头绪的排查时间。

拿一个实际的例子来说,比如你在做一个视频播放页面:

export default { onStart(want, launchParam) { console.info('Page onStart'); this.videoUrl = want?.parameters?.url ? want.parameters.url : ''; }, onActive() { console.info('Page onActive'); this.startPlayback(); // 播放器初始化完成,开始播 }, onInactive() { console.info('Page onInactive'); this.pausePlayback(); // 即将失去焦点,避免后台出声 }, onBackground() { console.info('Page onBackground'); this.releaseDecoder(); // 不可见了,释放解码器 }, onForeground() { console.info('Page onForeground'); this.restorePlaybackState(); // 回到前台,恢复进度和画面 }, onStop() { console.info('Page onStop'); this.monitorOff(); // 销毁,资源全部回收 } }

这段代码里,每个回调“只干自己该干的事”,注释和职责对得整整齐齐。实际项目里,如果你发现某个页面退后台再回来,状态老是错乱,八成就是onBackground和onForeground这对兄弟没成对使用。

2.2 两个页面互相跳转时,生命周期怎么联动

新手问得最多的问题是:从首页跳详情页,两边Ability的生命周期到底是个什么顺序?我直接说结论:先让旧页面让路,再放新页面上场。

假设你现在从A页跳B页,完整过程大致是:A进入onInactive(因为界面已经不在交互层最前面),B创建并走完onStart、onActive,B可见可交互;紧接着A进入onBackground(因为被B完全挡住了)。等你在B页点返回,顺序反过来,B先进入onInactive,A从后台被拉回前台走onForeground、onActive,B继续走onStop。

这里有个很多人踩过的坑:在A页的onInactive里去做数据保存,看起来合理,其实不完全可靠。因为onInactive之后,A并不一定会马上进入onStop,如果这时候B是一个半透明的卡片页面,A可能停留在一种“可见但不可操作”的状态,你保存数据之后又刷新了一下界面,那本次操作就白干了。稳妥的做法是:数据强一致性的操作放onBackground里,界面非关键展示的刷新放onActive里。

再补充一个组件初始化的问题。你在onStart里查不到某个组件的实例,不用急,你可以在onReady回调里拿(FA模型的JS UI场景下就是onReady之后组件树才完整)。我自己的习惯是:把拿组件的操作放在onReady或onActive里,把“给组件赋值”的动作也放在这两个回调之内,这样无论页面从冷启动还是从后台恢复,组件的可用性都有保障。

2.3 生命周期和应用切后台的配合

HarmonyOS是个多任务、多窗口能力很强的系统,用户可能随时从你页面里划走,去看另一个应用,也可能分屏同时用两个页面。Behavior分得很细致,你的Ability生命周期回调在分屏场景下可能比手机上更频繁地触发。这时候千万别在onBackground里做重活,比如把几百MB的内存数据写盘,系统可不会等你干完再切后台。我的经验是耗时操作一律丢后台任务队列,onBackground里只做“标记状态”和“释放最吃内存的资源”。

反过来onForeground也不是用来做“重计算”的地方。回到前台时,页面要的是快速恢复现场,你可以在onForeground里做两步:第一步恢复UI可见状态,第二步入队一个异步任务拉取最新数据。这两步分开,用户体感上就是“一回来内容还在,过一会儿数据悄悄更新”,不会出现卡顿或白屏。

3. Service Ability生命周期与后台任务管理

3.1 Service生命周期和Page有什么不同

Service Ability没有界面,所以它的生命周期比Page简单,但也正是因为没界面,容易让开发者忽略它的存在状态。FA模型下,Service Ability的关键回调是:

  • onStart:Service第一次被创建时调用,可以在这里初始化连接池、打开数据库。
  • onCommand:每次调用startAbility拉起Service时都会回调,注意是“每次”,适合处理本次启动要做的任务。
  • onConnect:当有前台组件通过connectAbility绑定到Service时调用,返回一个可调用的代理对象。
  • onDisconnect:所有绑定的前端都断开时回调。
  • onStop:Service销毁时回调,释放占用的资源。

在Stage模型下,写法上略有差异,Service被归类到ExtensionAbility里,生命周期简化为onCreate、onDestroy、onConnect等。但核心思想没变:Service本质上是给“无界面能力”服务的,它不依赖任何窗口状态。

我还记得之前写过一个小项目,用Service Ability在后台做数据拉取,前台页面通过connectAbility拿到它的代理,然后实时刷新进度条。这里有个关键细节:如果你只用了startAbility,Service是你的“单向操作工”,它干完活你不知道结果;如果你用了connectAbility,相当于跟Service建立了“一条双向沟通管道”,页面可以随时调用Service的方法,Service也可以主动向页面发通知。

3.2 startAbility和connectAbility到底怎么选

选择标准我建议看一句话:需不需要交互。

需要后台持续干活、不关心回传结果的,比如日志上报、文件清理,直接用startAbility,拉起之后各自安好,系统可以随时回收。

需要从Service实时取数据,或者要页面和Service反复通信的,比如音乐播放器的播放状态、下载任务的进度,必须用connectAbility,通过Service返回的代理来做方法调用。

代码上大概是这样:

// 拉起Service featureAbility.startAbility({ want: { bundleName: "com.example.music", abilityName: "PlayService" } }); // 绑定Service const service = await featureAbility.connectAbility({ bundleName: "com.example.music", abilityName: "PlayService" });

连接成功后的service对象,就是你在Service侧通过onConnect里return出来的远端代理。在connectAbility之前,最好先判断下服务是否已经拉起,避免连续点击按钮触发多次重复连接。

3.3 Data Ability的生命周期边界

说Data Ability是因为它和另两个有点不一样。Data Ability主要基于File、Database、Preferences这类数据存储能力对外提供服务,但它的生命周期并不是“随页面走”,它跟随的是“绑定”关系。系统在别的Ability访问Data Ability时,会把它拉起来,数据访问结束且不再有引用时,它有可能会被销毁。

正是因为Data Ability的这种特性,我建议开发者在设计时不要存放长期内存状态,所有数据读写都要走真正的持久化载体。如果你在Data Ability里开了一个大缓存,以为它能一直存活,后面等系统把它回收了,你的数据就凭空丢了,而且很难复现。Data Ability适合做“接口人”,不适合做“仓库看守人”。

4. Want意图跳转的实战与底层逻辑

4.1 一条Want里到底装了什么

HarmonyOS里,Want是用来描述“你接下来想干什么”的对象。你可以把它简单理解成一张快递单,既要写清收件地址,又要写清包裹备注。它几个核心字段是:

字段作用示例
bundleName目标应用包名com.example.demo
abilityName目标Ability名com.example.demo.MainAbility
action希望执行的动作描述ohos.want.action.view
entities能处理该动作的实体类别entity.system.browser
uri指向的数据资源标识dataability:///com.example.data
type预期数据的MIME类型text/plain
parameters附加参数集合{ "key": "value" }

对于跳转场景,bundleName和abilityName是绝对定位用的,写清楚就一定能跳到目标页面,这也就是所谓的显式Want。如果只写action和entities,不写具体的abilityName,系统会根据你的action在注册表里匹配出所有符合条件的能力,让用户选择或由系统默认处理,这就是隐式Want。

因为这两种模式差异非常大,我通常建议在自己的应用内部一律用显式Want,跨应用调用时再考虑隐式Want。为什么?显式Want开销低、定位准确、犯错马上能定位,缺点是你必须明确知道对方的包名;隐式Want灵活但匹配过程不好排查,一旦匹配不到,页面弹不出来,系统日志往往又不直观,排查成本高。

4.2 显式跳转三步走

页面跳转的写法并不复杂,但我想强调三个细节。先看一个完整示例:

import featureAbility from '@ohos.ability.featureAbility'; const wish = { bundleName: "com.example.app", abilityName: "com.example.app.SecondAbility", parameters: { loginToken: "abc123", source: "main_page" } }; featureAbility.startAbility({ want: wish, success: () => { console.info("跳转成功"); }, fail: (error) => { console.error("跳转失败: " + JSON.stringify(error)); } });

第一个细节是bundleName和abilityName的完整写法。abilityName很多初学者容易漏包名前缀,或者在DevEco Studio的module.json里写了别名,实际运行的时候匹配的是完整类名,没对上就跳不过去。

第二个细节是参数传递的序列化。parameters里的值最好是基础数据类型、数组、对象这些可以被序列化的,如果你塞了个回调函数或者一个持有native资源的对象进去,到了目标Ability那边,你会发现它根本没接住你原来的内容。我见过有人塞了一个Context进去,结果对方接到的是一串奇怪的ID,很不容易排查。

第三个细节是注入的want值可能改变生命周期。很多页面需要根据parameters的不同走不同的初始化逻辑,比如从支付页回来要刷新订单状态。这种场景下,你必须在目标Ability的onStart里第一时间去读参数并保存下来,不要等到onActive再去取,因为某些系统场景下want对象在延迟回调时已经被释放或者改变。

4.3 隐式Want和系统匹配规则

隐式Want的使用场景,最典型的就是打开一个网址、拉起一个系统地图、分享一段文本。它不需要知道具体哪个应用实现能力,系统会按action、entities、uri/type这套条件去匹配。

我举个例子,拉起系统的浏览器打开一个网页:

var want = { action: 'ohos.want.action.viewData', entities: ['entity.system.browser'], uri: 'https://www.example.com', type: 'text/plain' }; featureAbility.startAbility({ want: want });

这里action是“我要查看数据”,entities里写了“属于浏览器类实体”,uri是数据来源,type是数据类型。系统匹配时会把这四个条件一起做评估,任何一项不满足都不会出现在候选列表里。

避坑点来了:隐式Want如果匹配不到任何应用,startAbility的回调里会返回一个错误,但用户在界面上可能感受不到任何变化,以为自己的按钮没生效。所以代码写完一定要用fail回调把所有失败场景打点打出来,别等到测试来报“按钮没反应”,你才发现是意图没匹配上。

另外要注意路径区分的匹配规则。uri里如果带了具体host和path,匹配会更精确,但很多系统应用在注册时会模糊匹配,导致你以为该出现的应用没出现。遇到这种情况,先看看目标应用在module.json里是怎么声明intent filters的,别瞎猜。

4.4 带结果返回的跳转

跳转不只是“过去就完事”,相当多场景需要“带结果回来”,比如选图片、扫码、编辑资料。HarmonyOS里,发起方用startAbilityForResult,目标页完成后调用terminateSelfWithResult把数据带回来。

发起方代码:

featureAbility.startAbilityForResult({ want: { bundleName: "com.example.app", abilityName: "com.example.app.EditPage", parameters: { id: 9527 } }, success: (result) => { const ret = result.want?.parameters?.retValue; console.info(`拿到返回值: ${ret}`); }, fail: (error) => { console.error(`调用失败: ${JSON.stringify(error)}`); } });

目标页代码:

featureAbility.terminateSelfWithResult({ resultCode: 0, want: { parameters: { retValue: "保存成功" } } });

这里有个容易被忽略的地方:resultCode。很多写第一版跳转的人习惯随便给个0或者1,也不定义常量,等后面需求变成“三种不同状态分别处理”时,代码里全是魔法数字,读起来非常痛苦。我建议一开始就定义一组枚举,比如RESULT_OK、RESULT_CANCEL、RESULT_ERROR,然后按枚举判断。

还要提醒一句,terminateSelfWithResult之后,页面本身就被销毁了。如果目标页还依赖返回结果做后续操作,比如保存草稿,一定别把写盘动作放到terminateSelfWithResult之后,因为这条语句执行后,页面的代码可能已经不在可控状态了。正确顺序是:先处理好你的数据,再调用terminateSelfWithResult结束页面。

5. 生命周期与Want联动的调试避坑实录

5.1 页面跳转后结果丢失:多半是生命周期时序搞错了

有一次同事找我排查一个问题:从A页跳到B页,B页返回时,A页的数据没刷新。我一看代码,他把数据刷新写在onStart里。当时就觉得不对,因为B页返回A页时,A页不一定会重新触发onStart——它只是从后台被拉回前台,触发的是onForeground和onActive,onStart只会在销毁重建后才走。

这其实是个非常典型的“生命周期理解错位”问题。页面跳转有两种路径:如果A被系统回收了再回来,才会走完整生命周期;如果A只是退到后台,那它回到前台只走后半段生命周期。所以,凡是页面再次可见时都要执行的操作,放在onForeground/onActive里,不要放在onStart里。

对应的自适应方案是这样:页面初始化时在onStart里设置好静态数据,在onActive里发起首次数据请求,之后每次从次级页面返回时数据自动走一遍onActive刷新。这样逻辑统一,不需要额外维护一个“是否首次加载”的标志位,也不容易漏刷新。

5.2 Want参数传过去了,但页面读不到值

参数传不过去,常见原因有三个:字段名大小写不一致、序列化类型不兼容、读取时机太晚。先说字段名问题,parameters是个Map结构的对象,键名完全匹配才能取到,很多项目在定义常量时没有统一规范,发起方和接收方各写各的“token”和“Token”,找人排错半天最后发现是大小写。这种问题我建议在团队里统一一个“参数常量类”,所有跨页面参数名都从常量类里取,而不是手写字符串。

序列化类型不兼容也很常见。比如发起方传入的是一个Date对象,序列化后变成了字符串,接收方再用instanceof Date去判断,判断结果就是false。处理这类问题,前期做好约定,参数只传可序列化的普通对象,日期时间都转成时间戳字符串,枚举值统一传字符串,可以少很多烦恼。

5.3 拉起Service失败:常见权限和声明问题

Service Ability拉起失败,十个里有七个是module.json里的声明没写好。Service和Page一样需要在配置里声明,开发者有时候只写了页面,没写Service类型,或者声明了services但没写对name。如果系统日志报“unable to find ability”,优先检查配置文件,其次再排查bundleName和权限有没有对齐。

还有一个值得专门说的情况:调用方想拉起Service,但服务方声明了仅允许特定应用访问,这在跨应用场景特别常见。你的应用确实存在,但你不在这张白名单里,系统会拒绝分发这个Want。排查的时候先看错误码,如果是权限类错误,再看一下服务方配置里的visible和permission字段。

5.4 生命周期回调里的耗时操作会让跳转看起来卡顿

页面跳转的顺滑度,其实和生命周期回调里干的事情强相关。你如果让onStart或者onBackColor里去读一个大文件,或者同步拉取网络数据,你会发现页面半天出不来,甚至出现“点击后白屏几秒”的现象。

我用过的稳妥做法是,onStart里只做轻量初始化,耗时操作一律dispatch到任务队列异步执行。有两个场景要特别注意:需要在onStart里读取want参数然后放到缓存里,这是轻量的,可以同步;但如果你要根据参数从数据库里加载一整个列表再展示,建议把加载动作放到onActive之后异步执行,配合loading态给用户一个反馈,体验会明显不一样。

5.5 分屏和折叠屏场景下的生命周期异常

HarmonyOS的目标设备形态很杂,折叠屏和分屏场景又给生命周期加了不少新的复杂度。分屏时,两个页面同时可见,系统可能不会把另一个页面马上置为onBackground,而是让它保持在onInactive。这会导致一些依赖“onBackground保存数据”的逻辑不触发。

我当时做一个笔记应用,就遇到过分屏时用户写完一半切到右边,再切回来时笔记内容丢了的Bug。后来改成了“onInactive时也做一次轻量保存”,才把这个丢失问题解决掉。你也可以把自己的关键状态优先级分层:onInactive存轻量状态,onBackground存完整状态,onStop做销毁前兜底。这样无论系统怎么切,你的现场恢复能力都够。

6. 想顺手再多说两句的个人体会

Ability生命周期和Want这套机制,跟Android中Activity与Intent的对应关系,很多人会自觉或不自觉地往老经验上面靠。但我的实际感受是,HarmonyOS在很多细节上更“规矩”:它把能力分成页面、服务、数据三类,生命周期回调也更加明确,尤其是后台回收策略比传统Android体系要激进一些。你越早抛弃“Android怎么用我就怎么用”的惯性,越能少踩坑。

写代码这块,我自己这几年沉淀下来的三类习惯,分享给同行参考:核心业务逻辑不要写在生命周期回调里,收个参数、打个点、落个缓存就到此为止,真正的业务逻辑放独立Service或者工具类里;所有Want传参都需要在启动方和目标方两边都加日志,一旦出问题,日志是你最直接的排查路径;再就是每次开发完跳转功能,顺手用命令行工具检查一下module.json里的Ability声明是否完整,这五分钟的检查能避免连续半小时的错误排查。

如果你正准备搭建一个HarmonyOS项目,或者正在重构旧代码,我建议你在项目第一天就把“生命周期状态机”和“Want参数归档”这两个文档约定好,写进团队规范里。它带来的价值不是上线那一刻看到的,而是后面每一次页面改版、每一次跨团队联调、每一次线上排查时,你省下的时间会成倍回报你。

相关新闻

抽样调查课后答案怎么用?分层抽样公式推导与统计模拟验证指南

抽样调查课后答案怎么用?分层抽样公式推导与统计模拟验证指南

简介:《抽样调查理论与方法》(第二版)冯士雍课后答案,是一份面向统计学、应用数学及相关专业学生的习题参考答案文档,主要解决课后习题无从下手、答案不便核对的问题。文档内容与教材章节高度对应,覆盖随机…

2026/10/20 18:25:05 阅读更多 →
基于约束差分进化算法的Matlab多微电网拓扑优化实践

基于约束差分进化算法的Matlab多微电网拓扑优化实践

多微电网的拓扑设计,本质上是一个在成百上千个决策变量里找最优解的组合爆炸问题。传统做法靠人工经验和试凑,规模一上来就彻底失效。这篇博文要讲的是我用Matlab实现的一套基于约束差分进化算法(CDE)的大规模矩阵优化方法&#x…

2026/10/20 18:25:05 阅读更多 →
低代码工作流设计:从人工审批到智能驱动的关键实践

低代码工作流设计:从人工审批到智能驱动的关键实践

1. 先别急着画流程:给业务现状做一次“卡点体检”我见过太多团队拿到JNPF工作流设计器之后,第一件事就是打开画布,把采购审批、报销、合同会签全部拖一遍节点,两天做完一套看似漂亮的流程,上线之后却发现比原来的纸质流…

2026/10/20 18:25:05 阅读更多 →

最新新闻

MSA存储入门指南:从SAN协议到选型场景的全面解析

MSA存储入门指南:从SAN协议到选型场景的全面解析

简介:这份文档面向备考H3C认证工程师-MSA存储(H3CNE-MSA)的技术人员与H3C代理服务工程师,聚焦MSA存储设备基础配置与维护知识,帮助读者在有限时间内系统梳理考点、检验掌握程度。资源为1个docx文件,压缩包约…

2026/10/20 19:39:14 阅读更多 →
C语言大作业高分实践:工程结构、内存安全与评分对齐

C语言大作业高分实践:工程结构、内存安全与评分对齐

简介:这是一份面向高校C语言初学者与课程设计学生的高分期末大作业实战项目,完整实现了一个具备学生端与管理员双角色的学生成绩管理系统。资源包含可直接编译运行的C/Qt源码(含18个.h头文件与18个.cpp实现文件)、图形界面.ui文件…

2026/10/20 19:39:14 阅读更多 →
Redis Java客户端选型与实战:Jedis、Lettuce、Redisson对比

Redis Java客户端选型与实战:Jedis、Lettuce、Redisson对比

1. 先搞清楚需求,再选客户端写Java应用连Redis,第一步不是去翻依赖、复制代码,而是先想清楚:你的业务到底需要Redis做什么,以及你的应用是什么形态。这话可能听起来像废话,但我在实际项目里见过太多人一上来…

2026/10/20 19:39:14 阅读更多 →
轻量级AI助手ZeroClaw实战:有限算力下的部署与Agent落地

轻量级AI助手ZeroClaw实战:有限算力下的部署与Agent落地

1. 项目定位:为什么轻量级AI助手反而更实用去年年底我拿到一台配置平平的旧工作站,8GB内存、无独显、CPU还是几年前的型号,跑几个容器就喘。当时手头正好有个工具自动化需求:定时抓取内部系统数据,做简单清洗&#xff…

2026/10/20 19:39:14 阅读更多 →
单相桥式半控整流电路原理与Matlab/Simulink仿真建模分析

单相桥式半控整流电路原理与Matlab/Simulink仿真建模分析

单相桥式半控整流电路,这个名字在电力电子课程里出现的频率极高。很多电气工程专业的朋友第一次接触晶闸管整流,就是从它开始的。最近正好有人在问Matlab仿真的思路,我把自己做这个仿真报告的全过程梳理了一遍,从拓扑结构分析到模…

2026/10/20 19:39:14 阅读更多 →
Java动漫链接生成器:批量整理番剧资源链接的轻量工具

Java动漫链接生成器:批量整理番剧资源链接的轻量工具

简介:这是一款面向动漫资源采集与二次元工具开发者的轻量级命令行程序,基于Java实现,可根据指定标签批量生成动漫图片链接,适合需要批量获取Danbooru图源、做数据采集或练手Java命令行项目的开发者。资源包共17个文件,…

2026/10/20 19:38:12 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50: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/20 9:50:45 阅读更多 →