HarmonyOS鸿蒙Next中服务卡片显示问题定位指导
场景描述
众多HarmonyOS鸿蒙Next应用在开发服务卡片时,会经常出现卡片白屏和卡片数据显示异常的问题。可能出现的原因是由于没有遵循卡片的约束限制,导致节点未正确挂载等一系列问题。
服务卡片使用出现白屏
现象:
桌面上已加载的卡片,在开发调试过程中或者系统升级后突然出现白屏,遇到这种情况开发者常常不知如何排查这类问题。
分析:
卡片白屏分为两种情况:白色绘制在FormComponent
上,这个属于卡片没有正确加载;白色绘制在卡片内容的根节点上,这个属于卡片内容没有正常挂载,根据dump
出ArkUI
节点树、rsNode
节点树进行判断。
-
抓取
ArkUI
节点树和rsNode
节点树保持手机亮屏状态,将以下代码生成“获取
arkui
控件节点树.bat”并双击,输入对应Focus window
后回车即可得到ArkUI
节点树hdc shell param set persist.ace.debug.enabled 1 hdc shell "hidumper -s WindowManagerService -a '-a'" [@set](/user/set) /p windowId=input WindowId : for /F %%i in ('hdc shell "find data/ -name arkui.dump"') do ( hdc shell "rm %%i" ) ::old pipeline ::hdc shell "hidumper -s WindowManagerService -a '-w %windowId% -render -c'" ::ng hdc shell "hidumper -s WindowManagerService -a '-w %windowId% -element -c'" > arkui.dump for /F %%i in ('hdc shell "find data/ -name arkui.dump"') do ( hdc file recv %%i . ) pause
-
抓取
ArkUI
节点树后,搜索应用名,通过compid
判断是当前卡片的FormComponent
,如下图,白色绘制在com.example.startability
的FormComponent
上,卡片默认颜色是透明色,如果出现白色,说明卡片被置成不可信卡片,这种情况大多是应用在代码里写了死循环导致阻塞JS线程等。 -
也可以通过
DevEco Testing
判断,如下图是修正代码后卡片正常展示的效果实用工具 -->UIViewer
--> 获取页面 --> 选中卡片 --> 此时展开右侧高亮Stack
-->Common
-->FormComponent
即可查看。 -
根据以下代码生成“获取
rs
节点树.bat”文件,拿到rsNode
节点树,通过上图ArkUI
节点的CanvasNodeId
找到对应的rsNode
卡片根节点,根节点下面的节点就是卡片提供方的内容节点,从以下截图可以看出,白色绘制在卡片内容的根节点上,这种情况属于卡片正常加载了,但是卡片的内容没有加载,具体原因需要结合日志分析:
注意点:
- 对于共享包,不管是直接引入还是间接引入,都是不支持的。
- 不支持断点调试 && 不允许使用
hilog
(虽然部分开发者将hilog
作为外部组件引入,导致IDE
校验失败,但是实际上这是不合规范的,可能也会导致白卡的问题),推荐开发者使用原生console.log
进行日志打印。 - 对于是否支持的模块,注意区分卡片能力和元服务
API
,标识卡片能力的组件是支持在卡片内使用的。 - 对于以
memory://fileName)
的方式加载的图片,卡片的内存中只保留5张2M以下的图片,其他图片将会更新失败。 - 对于定时刷新,系统规格最小间隔时间是30min,如需每分钟更新建议使用
TextClock
组件(不建议监听公共事件usual.event.TIME_TICK
)。
- 取出全量日志,搜索关键字
ArkCompiler
,按照关键日志排查
-
当出现关键字:
Cannot get SourceMap info, dump raw stack
一般是开发者的API
写法错误,或者引入了不支持卡片的模块,导致了相关模块的报错,从而导致卡片内容加载失败出现白屏。 -
如果
TypeError
:Cannot read property xxx
的属性是业务自己的变量,业务方自己规避。如图,这是由于ZXGWidgetCardLarge.ts
文件中使用startsWith
的地方写法问题导致 -
如果
TypeError
:Cannot read property xxx
的属性是系统模块,需要明确当前模块是否支持服务卡片。若明确支持,需要进一步分析 -
当出现关键字
module can't load in form ,moduleName=xxx
可能是预加载文件变更,与卡片服务白名单未匹配造成。需开发者去掉当前报错模块。 -
当
com.ohos.formrenderservice
中出现关键日志can't find this page xxx
一般是.abc
文件打包时出现了问题,需要应用确认hap
包里WidgetCard.abc
是否存在,位置是否正确。建议Clean project
后,重新编译运行
卡片数据更新异常
现象:
卡片首次正常加载,点击卡片,主动更新图片数据时出现异常。
分析:
卡片数据更新流程:Card.ets
中触发postCardAction
发送message
事件,拉起FormExtensionAbility
,然后由FormExtensionAbility
调用updateForm
将数据信息传输到卡片管理服务,经FMS
将所有图片整合到imagemap
中进行缓存,再由卡片渲染服务取出缓存信息进行组件渲染。这里卡片数据展示异常主要根据具体的实现逻辑结合日志一起分析。
以下是UpdateForm
图片和数据传输流程:
-
关键日志
FormManagerService
,如果有Get file size failed, errno is 0
这种Error
信息说明开发者在updateForm
时传的fd
有问题,导致更新数据时,图片写入内存失败。 -
当出现关键日志
formJsInfo.imageDataMap.size = xxx
,如果xxx
与updateform
传的图片数量一致,那么fms
传给frs
的图片信息正常,基本可以判断应用传递给imagemap
写入图片数据正常。 -
当出现关键日志
load SharedMemoryImage timeout!
一般是卡片内加载了多个网络图片,并超出了卡片内存限制。为防止图片占用内存太多,当前卡片的规格只保留5张2M以下的图片,其他图片30s后会被clear
。
FAQ:
-
卡片数据存储在本地持久化数据里,依次添加多个卡片,手机重启后,卡片全部变成最新添加的。
A:手机重启,会重新走一遍
AddForm
回调,需要确认持久化数据是否为一对多 -
对于卡片内存的限制,除了控制在内存范围内,还有别的规避方案吗?
A:使用网络图片会有该限制,开发者可以将图片预置在
resource
中规避
更多关于HarmonyOS鸿蒙Next中服务卡片显示问题定位指导的实战教程也可以访问 https://www.itying.com/category-93-b0.html