HarmonyOS鸿蒙Next中如何解决Canvas画板绘制多条路径时缩放过程中出现的APP闪退
HarmonyOS鸿蒙Next中如何解决Canvas画板绘制多条路径时缩放过程中出现的APP闪退
【问题现象】
使用离屏画布画出线条进行缩放时,发生APP闪退,没有堆栈信息。
【背景知识】
使用Canvas组件或Canvas API时,渲染、动画和用户交互通常发生在应用程序的主线程上,与画布动画和渲染相关的计算可能会影响应用程序性能。OffscreenCanvas提供了一个可以在屏幕外渲染的画布,这样可以在单独的线程中运行一些任务,从而避免影响应用程序主线程性能。
【定位思路】
-
APP发生闪退一般是由Crash和内存溢出引起,由于没有堆栈信息,先排查是否发生内存溢出。通过DevEco Studio自带的profile工具,发现Canvas缩放过程中,该应用的内存占用一直在往上涨,并且长时间无法释放,直到APP闪退,如图所示内存占用1.6G。
-
查看缩放代码,离屏画布的大小会被修改,且调用次数频繁,最终导致内存不断变大。
【解决方案】
-
在手势缩放事件发生时,设置阈值,减少缩放变化次数,进而减少画布重绘次数。
// 变化量超过阈值,才会促发更新 .gesture( PanGesture() ... .onActionUpdate((event: GestureEvent) => { if (Math.abs(offsetX - this.lastOffsetX) < 0.5 && Math.abs(offsetY - this.lastOffsetY) < 0.5) { return; } this.lastOffsetX = offsetX this.lastOffsetY = offsetY // 计算height ... }) ... )
-
使用Canvas组件替换离屏画布。
build() { Column() { Column() { Column() { Canvas(this.context).width('100%').height('100%') .onReady(() => { this.context.canvas.scale(this.height / 100, this.height / 100) this.context.canvas.drawLine(50, 50, 160, 160) this.context.invalidate() }) } .border({ width: 2, color: "# 66F1CCB8" }) // 边框,仅用于展示效果 } .backgroundColor("# FFFFFF") .height(this.height) .width(this.height) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) ... } }
修改后结果:
DevEco Studio内存检查显示不会飙升,没发生APP闪退现象。
【总结】
Canvas的宽高变化会导致重绘,频繁变化会导致离屏画布的内存占用变多,进而引发APP闪退,缩放场景可以使用Canvas替换。
更多关于HarmonyOS鸿蒙Next中如何解决Canvas画板绘制多条路径时缩放过程中出现的APP闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中如何解决Canvas画板绘制多条路径时缩放过程中出现的APP闪退的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,解决Canvas画板绘制多条路径时缩放过程中出现的APP闪退问题,可以采取以下两种方法:
-
设置缩放阈值:在手势缩放事件中,设置变化量阈值,减少缩放变化次数,从而降低画布重绘频率。例如,仅当偏移量变化超过0.5时才触发更新。
-
替换离屏画布为Canvas组件:直接使用Canvas组件代替离屏画布,避免频繁修改离屏画布大小导致的内存占用问题。确保Canvas的宽高变化不会引发频繁重绘。
修改后,DevEco Studio内存检查显示内存占用稳定,APP闪退问题得到解决。