HarmonyOS APP实战-画图APP - 第14篇:可变帧率与性能优化
HarmonyOS APP实战-画图APP - 第14篇使用displaySync定制绘制帧率开篇上一篇我们完成了本地数据库存储与读取功能通过关系型数据库RdbStore保存了画作元数据名称、创建时间、缩略图路径并实现了画作列表页面支持从列表加载已有画作继续编辑。数据库模块是画图APP的数据持久化基石。本篇将聚焦性能优化——根据绘制内容的复杂度动态调整绘制帧率。画图APP在画笔手绘时需要高帧率60fps保证跟手性而空闲状态或显示静态图形时可以降低帧率至30fps以减少功耗。HarmonyOS提供了displaySyncAPI允许开发者针对自绘制内容指定不同的目标帧率。我们将封装一个FrameRateController模块并在DrawingCanvas组件中集成它实现按需切换帧率。核心实现基础配置导入与常量定义首先在模块顶部导入displaySync并定义帧率常量。// FrameRateController.etsimport{displaySync}fromohos.graphics.displaySync;/** * 帧率常量 */exportconstFRAME_RATE_HIGH60;// 高帧率模式画笔绘制时exportconstFRAME_RATE_LOW30;// 低帧率模式静止或浏览时关键点说明ohos.graphics.displaySync是ArkGraphics 2D提供的可变帧率能力模块。帧率值单位是fps帧每秒60fps适合手绘追踪30fps满足静态显示且降低功耗。核心逻辑FrameRateController类FrameRateController负责创建和管理DisplaySync实例并根据业务状态设置目标帧率。// FrameRateController.etsexportclassFrameRateController{privatedisplaySyncInstance:displaySync.DisplaySync|nullnull;privateisRunning:booleanfalse;privatecurrentRate:numberFRAME_RATE_LOW;/** * 初始化DisplaySync实例 * param requestId 请求标识用于区分不同绘制场景 */publicasyncinit(requestId:string):Promisevoid{if(this.displaySyncInstance){return;}try{this.displaySyncInstanceawaitdisplaySync.create(requestId);console.info(FrameRateController: DisplaySync created with requestId${requestId});}catch(err){console.error(FrameRateController: create failed, error${JSON.stringify(err)});}}/** * 启动帧率控制 * param frameCallback 每帧回调参数为时间戳 */publicstart(frameCallback:(timestamp:number)void):void{if(!this.displaySyncInstance||this.isRunning){return;}this.displaySyncInstance.start(frameCallback);this.isRunningtrue;console.info(FrameRateController: started);}/** * 停止帧率控制 */publicstop():void{if(!this.displaySyncInstance||!this.isRunning){return;}this.displaySyncInstance.stop();this.isRunningfalse;console.info(FrameRateController: stopped);}/** * 更新目标帧率 * param rate 新的帧率值fps */publicupdateFrameRate(rate:number):void{if(!this.displaySyncInstance){console.warn(FrameRateController: instance not initialized);return;}try{this.displaySyncInstance.setExpectedFrameRate(rate);this.currentRaterate;console.info(FrameRateController: frame rate updated to${rate}fps);}catch(err){console.error(FrameRateController: setExpectedFrameRate failed, error${JSON.stringify(err)});}}/** * 销毁DisplaySync实例 */publicdestroy():void{if(this.displaySyncInstance){this.displaySyncInstance.destroy();this.displaySyncInstancenull;this.isRunningfalse;console.info(FrameRateController: destroyed);}}/** * 获取当前帧率 */publicgetCurrentRate():number{returnthis.currentRate;}}关键点说明displaySync.create(requestId)是一个异步方法返回PromiseDisplaySync实例。setExpectedFrameRate(rate)设置期望帧率系统会尽量按照该值调度。start(callback)开始帧率控制回调参数为时间戳纳秒可用于驱动动画循环。destroy()释放资源在页面销毁时调用。实际项目中帧率回调可以作为绘制驱动的定时器替代setInterval或requestAnimationFrame提供更精确的帧同步。完整模块集成到DrawingCanvas组件DrawingCanvas是画图APP的核心绘制组件。我们在其中集成FrameRateController在触摸开始/移动时切换到高帧率触摸结束或闲置时降回低帧率。同时为了兼容原有绘制逻辑我们将帧率回调绑定到画布重绘操作。// DrawingCanvas.ets简化版仅展示集成逻辑import{CanvasRenderingContext2D}fromohos.graphics.ui;import{FrameRateController,FRAME_RATE_HIGH,FRAME_RATE_LOW}from./FrameRateController;import{Point,DrawCommand}from../model/DrawCommand;// 假设自定义模型Componentexportstruct DrawingCanvas{privatesettings:RenderingContextSettingsnewRenderingContextSettings(true);privatecontext:CanvasRenderingContext2DnewCanvasRenderingContext2D(this.settings);privateframeCtrl:FrameRateControllernewFrameRateController();privateisDrawing:booleanfalse;privatelastTouch:Point{x:0,y:0};// ... 其他属性aboutToAppear(){// 初始化DisplaySyncrequestId可自定义this.frameCtrl.init(drawing_canvas_main).then((){// 启动帧率控制将回调连接到画布刷新this.frameCtrl.start((timestamp:number){// 这里可以驱动持续的绘制更新例如动画// 对于手绘我们只在触摸事件中局部重绘此回调暂不开启批量重绘// 但保持帧率控制活跃});// 初始设为低帧率this.frameCtrl.updateFrameRate(FRAME_RATE_LOW);});}onTouch(event:TouchEvent){if(!this.frameCtrl)return;switch(event.type){caseTouchType.Down:this.isDrawingtrue;// 触摸开始时切换到高帧率保证跟手this.frameCtrl.updateFrameRate(FRAME_RATE_HIGH);this.lastTouch.xevent.touches[0].x;this.lastTouch.yevent.touches[0].y;// 开始新路径this.startNewPath(this.lastTouch);break;caseTouchType.Move:if(this.isDrawing){constcurrent{x:event.touches[0].x,y:event.touches[0].y};// 添加点到当前路径并绘制this.addPointToPath(current);this.lastTouchcurrent;}break;caseTouchType.Up:caseTouchType.Cancel:// 绘制结束恢复低帧率if(this.isDrawing){this.finishPath();this.isDrawingfalse;this.frameCtrl.updateFrameRate(FRAME_RATE_LOW);}break;}}privatestartNewPath(point:Point):void{// 原有逻辑开始一个新的Path}privateaddPointToPath(point:Point):void{// 原有逻辑向Path增加点并调用context.drawPath()}privatefinishPath():void{// 原有逻辑结束路径并保存到历史}aboutToDisappear(){this.frameCtrl.stop();this.frameCtrl.destroy();}build(){Canvas(this.context).width(100%).height(100%).onTouch((event:TouchEvent)this.onTouch(event))}}议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_urlplaceholder.pngpos_idimg-K54aM3fo-1783906018434)关键点说明aboutToAppear中初始化FrameRateController并启动默认低帧率。在onTouch的Down事件中更新为高帧率Up或Cancel时恢复低帧率。注意帧率回调本身不涉及重绘但保持start可以让系统按照目标帧率调度实际绘制仍由触摸事件触发。aboutToDisappear中停止并销毁实例防止内存泄漏。如果后续需要实现动画绘制如动态渐变、粒子效果可以利用frameCallback的时间戳驱动逐帧重绘此时帧率控制效益更明显。运行验证在画图APP中打开任意画布文件或新建画布用手指在画布上绘制当手指按下并移动时CPU/GPU会按60fps渲染轨迹体验流畅跟手。当手指抬起后帧率会降为30fps此时进行菜单操作或查看静态内容手机功耗降低。开发者可以通过DevEco Studio的Profiler工具查看帧率变化运行APP点击“性能分析”在“帧率时间线”中观察绘制时段帧率约60fps闲置时段约30fps。如果未看到切换请确认displaySync已正确初始化和权限设置无需额外权限。另外模拟器可能不完全支持帧率动态调节建议在真机上测试。小结与预告本篇实现了画图APP的帧率动态调节功能通过FrameRateController模块封装displaySyncAPI根据绘制活动自动切换60fps和30fps在保持手绘跟手性的同时减少闲置功耗。该模块是性能优化的重要一环可直接复用至其他自绘制场景。下一篇《使用overdraw工具检测性能》将介绍如何利用HarmonyOS的过度绘制调试工具Overdraw Debug分析画布绘制效率识别冗余绘制层次并通过Canvas的clip、clearRect等技术优化绘制指令进一步提升流畅度。

相关新闻

新型电力系统下基于二阶锥最优潮流的配电网分布式光伏接入承载力评估(Matlab代码实现)

新型电力系统下基于二阶锥最优潮流的配电网分布式光伏接入承载力评估(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

2026/7/14 0:53:32 阅读更多 →
AIGC检测用什么工具?2026年主流合规工具整理分享

AIGC检测用什么工具?2026年主流合规工具整理分享

2026年国内高校、期刊对学术内容的原创性审核不断升级,除了传统的论文重复率检测,AIGC生成内容检测已经成为必查项。本科毕业论文抽检、硕士学位论文答辩、职称评审论文送审、期刊投稿初审,一旦AI生成内容占比不符合官方要求,直接…

2026/7/14 0:49:32 阅读更多 →
基于改进 ICEEMDAN 的火电 - 蓄电池 - 飞轮混合储能联合调频协同控制策略研究(Matlab代码实现)

基于改进 ICEEMDAN 的火电 - 蓄电池 - 飞轮混合储能联合调频协同控制策略研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

2026/7/14 0:49:32 阅读更多 →

最新新闻

PyTorch数据加载实战:从torchvision.datasets到DataLoader的完整流程(以CIFAR10和MNIST为例)

PyTorch数据加载实战:从torchvision.datasets到DataLoader的完整流程(以CIFAR10和MNIST为例)

1. PyTorch数据加载基础:认识torchvision.datasets 当你刚开始接触PyTorch时,数据加载可能是最让人头疼的部分之一。别担心,torchvision.datasets模块就是专门为解决这个问题而生的。这个模块内置了多种常用的计算机视觉数据集,比…

2026/7/14 12:57:11 阅读更多 →
3个核心技巧快速掌握Python财经数据获取:AKShare实战指南

3个核心技巧快速掌握Python财经数据获取:AKShare实战指南

3个核心技巧快速掌握Python财经数据获取:AKShare实战指南 【免费下载链接】akshare AKShare is an elegant and simple financial data interface library for Python, built for human beings! 开源财经数据接口库 项目地址: https://gitcode.com/gh_mirrors/aks…

2026/7/14 12:55:10 阅读更多 →
终极Bilibili旧版恢复指南:3分钟找回经典B站体验

终极Bilibili旧版恢复指南:3分钟找回经典B站体验

终极Bilibili旧版恢复指南:3分钟找回经典B站体验 【免费下载链接】Bilibili-Old 恢复旧版Bilibili页面,为了那些念旧的人。 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Old 你是否还在为B站新版界面感到陌生和不习惯?加载…

2026/7/14 12:53:10 阅读更多 →
工业质检效率提升10倍:Cosmos-AnomalyGen-Metal-2B的自动化缺陷图像生成流程

工业质检效率提升10倍:Cosmos-AnomalyGen-Metal-2B的自动化缺陷图像生成流程

工业质检效率提升10倍:Cosmos-AnomalyGen-Metal-2B的自动化缺陷图像生成流程 【免费下载链接】Cosmos-AnomalyGen-Metal-2B 项目地址: https://ai.gitcode.com/hf_mirrors/nvidia/Cosmos-AnomalyGen-Metal-2B Cosmos-AnomalyGen-Metal-2B是一款由NVIDIA开发…

2026/7/14 12:51:08 阅读更多 →
OnscripterYuri Docker跨平台编译:一键构建所有支持的平台

OnscripterYuri Docker跨平台编译:一键构建所有支持的平台

OnscripterYuri Docker跨平台编译:一键构建所有支持的平台 【免费下载链接】OnscripterYuri An enhancement ONScripter project porting to many platforms, especially web. 项目地址: https://gitcode.com/gh_mirrors/on/OnscripterYuri 🚀 想…

2026/7/14 12:49:08 阅读更多 →
R项目部署与Docker容器化:构建可移植的高效环境终极指南

R项目部署与Docker容器化:构建可移植的高效环境终极指南

R项目部署与Docker容器化:构建可移植的高效环境终极指南 【免费下载链接】efficientR Efficient R programming: a book 项目地址: https://gitcode.com/gh_mirrors/ef/efficientR 你是否正在寻找R项目部署的最佳实践?想要掌握Docker容器化技术来…

2026/7/14 12:49:08 阅读更多 →

日新闻

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

更多请点击: https://kaifayun.com 第一章:AI Agent数据越界行为的合规性挑战与溯源必要性 AI Agent在自主执行任务过程中,可能因提示注入、上下文污染或权限配置缺陷,无意或有意访问、缓存、传输受保护数据(如PII、G…

2026/7/14 0:01:13 阅读更多 →
Perplexity vs ChatGPT vs Claude:实测127组复杂查询任务,谁才是真正可靠的“事实型AI助手”?

Perplexity vs ChatGPT vs Claude:实测127组复杂查询任务,谁才是真正可靠的“事实型AI助手”?

更多请点击: https://codechina.net 第一章:Perplexity 怎么用 Perplexity 是衡量语言模型预测能力的核心指标,数值越低表示模型对文本序列的不确定性越小、预测越精准。它本质上是交叉熵损失的指数形式,计算公式为:…

2026/7/14 0:01:13 阅读更多 →
全球首发!五一视界定制物理AI卫星ECS-1剑指万亿赛道

全球首发!五一视界定制物理AI卫星ECS-1剑指万亿赛道

五一视界发布公告,近日,公司与环天智慧科技股份有限公司(“环天智慧”)正式达成空天领域战略合作。环天智慧是国内领先、聚焦天基对地观测遥感卫星总体研制与在轨运营的商业航天企业,同时也是西南地区规模最大、具备全自主可控遥感卫星星座建…

2026/7/14 0:03:13 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/13 4:38:36 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/13 4:38:38 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/14 7:15:24 阅读更多 →

月新闻