多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

HarmonyOS 7 系统能力 04|通知提醒

HarmonyOS 7 系统能力 04|通知提醒 这一篇解决的问题通知发出去了为什么没看到。我们不背 API而是从一个真实页面需求出发把“本地通知发布与权限检查”做成能继续扩展的工程写法。先说问题功能能跑不等于接对了做 HarmonyOS 7 页面时最容易出现一种情况UI 已经写完按钮也摆好了等真正接系统能力时才发现权限、生命周期、异常分支和页面状态全挤在一起。第一次点可能没问题第二次点、拒绝权限、切后台再回来问题就开始冒出来。这也是这一套连载想解决的事。我们不把系统能力当成“调用一个 API 就结束”而是把调用前、调用中、调用后都放进页面流程里。这样代码才像项目代码而不是演示代码。1. 先把页面状态理顺无论调用哪一种系统能力页面至少要知道三件事当前是否正在执行、执行结果是什么、失败后用户能不能继续操作。先给页面准备一个最小状态模型。EntryComponentstruct DemoPage{StateisRunning:booleanfalseStatemessage:string等待操作build(){Column({space:16}){Text(this.message).fontSize(18)Button(this.isRunning?处理中...:开始操作).enabled(!this.isRunning).onClick(async(){awaitthis.runAction()})}.width(100%).padding(24)}privateasyncrunAction():Promisevoid{this.isRunningtruetry{this.message执行成功}catch(error){this.message执行失败请重试}finally{this.isRunningfalse}}}这段代码看起来很普通但它先解决了一个工程问题系统调用和 UI 状态不能各写各的。finally也不是装饰。成功、失败都要恢复按钮否则某个异常分支漏掉状态恢复页面就会一直停在“处理中”。2. 本地通知发布与权限检查真正接能力时不建议直接把一大坨调用逻辑塞进onClick。按钮只负责表达“用户做了什么”能力调用放进独立方法。后面加权限判断、日志、异常提示时页面结构不会迅速失控。privateasyncexecute():Promisevoid{if(this.isRunning){return}this.isRunningtruethis.message正在处理try{constresultawaitthis.callSystemAbility()this.messageresult?操作完成:没有获取到结果}catch(error){console.error(system ability error:${JSON.stringify(error)})this.message操作失败}finally{this.isRunningfalse}}privateasynccallSystemAbility():Promiseboolean{// 此处替换为本篇对应的 HarmonyOS 7 系统能力调用。returntrue}这里有个很实用的习惯方法返回的是业务需要的结果而不是把底层对象直接扔给页面。页面只关心“能不能继续渲染”不应该知道底层每个字段。项目一大这个区别很明显。3. 不要只写成功路径教程代码最爱写“点击 → 成功 → 展示结果”。真实用户偏偏不会这么配合。权限可能拒绝资源可能不存在系统能力可能暂时不可用应用也可能在执行中进入后台。所以页面至少把结果拆成三类成功、用户可恢复的失败、暂时无法恢复的失败。不要所有异常都只弹一句“操作失败”。用户看不懂开发排查也没信息。enumActionStatus{Idle,Running,Success,RetryableError,Error}Statestatus:ActionStatusActionStatus.IdleprivateshowResult(status:ActionStatus):string{switch(status){caseActionStatus.Running:return正在处理...caseActionStatus.Success:return处理完成caseActionStatus.RetryableError:return暂时失败可以重试caseActionStatus.Error:return当前无法完成操作default:return等待操作}}用枚举比堆几个 boolean 更稳。否则很容易同时出现loading true、success true、error true这种自己都解释不通的组合。4. 页面和系统能力之间最好隔一层项目里如果多个页面都要使用同一种系统能力复制代码是最省事、也是后面最麻烦的方案。更合适的方式是做一个很薄的 Service。它不负责 UI只负责调用、整理返回值和抛出明确错误。exportinterfaceAbilityResult{success:booleanmessage:string}exportclassSystemAbilityService{asyncexecute():PromiseAbilityResult{try{// 调用 HarmonyOS 7 对应能力return{success:true,message:success}}catch(error){console.error(execute failed:${JSON.stringify(error)})return{success:false,message:failed}}}}页面拿到的是稳定的AbilityResult。以后底层 API 调整优先改 Service不需要十几个页面一起找。这个做法不复杂却是“示例代码”和“项目代码”之间很明显的一道分界线。5. 真机测试时重点看什么系统能力相关功能不能只盯模拟器。模拟器适合确认页面流程和基础代码但涉及权限、硬件、后台行为时真机结果更有参考价值。测试时至少走一遍正常路径、拒绝路径、重复点击、切后台再返回以及失败后的再次尝试。还有一个很常见的坑第一次调用成功就认为代码结束了。实际线上问题往往发生在第二次、第三次调用。比如状态没有清理、上一次结果残留、按钮重复触发、页面销毁后异步结果又回来。写系统能力时把“重复执行”当成默认场景代码会稳很多。这一篇记住三件事第一系统能力不是一个孤立 API它一定会和页面状态、权限、异常分支发生关系。第二按钮事件保持短把具体调用放进方法或 Service。第三别只测试成功一次重复调用和失败恢复才更容易暴露真实问题。这一套思路会贯穿后面的 02–10。下一篇继续往真实功能里走不停留在概念层。小练习把本文的DemoPage改成你项目里的一个真实按钮并补上Idle / Running / Success / Error四种状态。然后连续操作三次再故意制造一次失败观察页面能不能正确恢复。能做到这一点再往里接具体系统 API会轻松很多。
返回列表