【入门到精通】鸿蒙next开发:服务卡片显示问题定位指南

往期鸿蒙5.0全套实战文章必看:(文中附带全栈鸿蒙5.0学习资料)


服务卡片显示问题定位指南

场景描述

众多应用在开发服务卡片时,会经常出现卡片白屏和卡片数据显示异常的问题。可能出现的原因是由于没有遵循卡片的约束限制,导致节点未正确挂载等一系列问题。

  • 服务卡片使用出现白屏

现象:桌面上已加载的卡片,在开发调试过程中或者系统升级后突然出现白屏,遇到这种情况开发者常常不知如何排查这类问题。

39.png

40.png

分析:卡片白屏分为两种情况:白色绘制在FormComponent上,这个属于卡片没有正确加载;白色绘制在卡片内容的根节点上,这个属于卡片内容没有正常挂载,根据dump出ArkUI节点树、rsNode节点树进行判断。

1、抓取ArkUI节点树和rsNode节点树

  • 保持手机亮屏状态,将以下代码生成"获取arkui控件节点树.bat"并双击,输入对应Focus window后回车即可得到ArkUI节点树
    hdc shell param set persist.ace.debug.enabled 1 
     
    hdc shell "hidumper -s WindowManagerService -a '-a'" 
    @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
    

    41.png

  • 抓取ArkUI节点树后,搜索应用名,通过compid判断是当前卡片的FormComponent,如下图,白色绘制在com.example.startability的FormComponent上,卡片默认颜色是透明色,如果出现白色,说明卡片被置成不可信卡片,这种情况大多是应用在代码里写了死循环导致阻塞JS线程等。

    42.png

  • 也可以通过DevEco Testing判断,如下图是修正代码后卡片正常展示的效果实用工具 --> UIViewer --> 获取页面 -->选中卡片 --> 此时展开右侧高亮Stack --> Common --> FormComponent即可查看。

    43.png

    44.png

  • 根据以下代码生成"获取rs节点树.bat”文件,拿到rsNode节点树,通过上图ArkUI节点的CanvasNodeId找到对应的rsNode卡片根节点,根节点下面的节点就是卡片提供方的内容节点,从以下截图可以看出,白色绘制在卡片内容的根节点上,这种情况属于卡片正常加载了,但是卡片的内容没有加载,具体原因需要结合日志分析:

45.png

      2、对照约束与限制检查代码是否符合规范。

注意点:

a. 对于共享包,不管是直接引入还是间接引入,都是不支持的。

b. 不支持断点调试&&不允许使用hilog(虽然部分开发者将hilog作为外部组件引入,导致IDE校验失败,但是实际上这是不合规范的,可能也会导致白卡的问题),推荐开发者使用原生console.log进行日志打印。

c. 对于是否支持的模块,注意区分卡片能力和元服务API,标识卡片能力的组件是支持在卡片内使用的。

46.png

d. 对于以memory://fileName) 的方式加载的图片,卡片的内存中只保留5张2M以下的图片,其他图片将会更新失败。

e. 对于定时刷新,系统规格最小间隔时间是30min,如需每分钟更新建议使用TextClock组件(不建议监听公共事件usual.event.TIME_TICK)。

3、取出全量日志,搜索关键字ArkCompiler,按照关键日志排查

a. 当出现关键字:Cannot get SourceMap info, dump raw stack一般是开发者的API写法错误,或者引入了不支持卡片的模块,导致了相关模块的报错,从而导致卡片内容加载失败出现白屏。

  • 如果TypeError:Cannot read property xxx 的属性是业务自己的变量,业务方自己规避。如图,这是由于ZXGWidgetCardLarge.ts文件中使用startsWith的地方写法问题导致

    47.png

    ​​​​​​​​​​​​

  • 如果TypeError:Cannot read property xxx 的属性是系统模块,需要明确当前模块是否支持服务卡片。若明确支持,需要进一步分析

b. 当出现关键字module can't load in form ,moduleName=xxx可能是预加载文件变更,与卡片服务白名单未匹配造成。需开发者去掉当前报错模块。

48.png

c. 当com.ohos.formrenderservice中出现关键日志can't find this page xxx一般是.abc文件打包时出现了问题,需要应用确认hap包里WidgetCard.abc是否存在,位置是否正确。建议Clean project后,重新编译运行

49.png

50.png

  • 卡片数据更新异常

现象:卡片首次正常加载,点击卡片,主动更新图片数据时出现异常。

51.png

分析:卡片数据更新流程:Card.ets中触发postCardAction发送message事件,拉起FormExtensionAbility,然后由FormExtensionAbility调用updateForm将数据信息传输到卡片管理服务,经FMS将所有图片整合到imagemap中进行缓存,再由卡片渲染服务取出缓存信息进行组件渲染。这里卡片数据展示异常主要根据具体的实现逻辑结合日志一起分析。

以下是UpdateForm图片和数据传输流程:

52.png

1、关键日志FormManagerService,如果有Get file size failed, errno is 0这种Error信息说明开发者在updateForm时传的fd有问题,导致更新数据时,图片写入内存失败。

53.png

2、当出现关键日志formJsInfo.imageDataMap.size = xxx ,如果xxx与updateform传的图片数量一致,那么fms传给frs的图片信息正常,基本可以判断应用传递给imagemap写入图片数据正常。

3、当出现关键日志 load SharedMemoryImage timeout!一般是卡片内加载了多个网络图片,并超出了卡片内存限制。为防止图片占用内存太多,当前卡片的规格只保留5张2M以下的图片,其他图片30s后会被clear。

54.png

FAQ

1、卡片数据存储在本地持久化数据里,依次添加多个卡片,手机重启后,卡片全部变成最新添加的。

A:手机重启,会重新走一遍AddForm回调,需要确认持久化数据是否为一对多

2、对于卡片内存的限制,除了控制在内存范围内,还有别的规避方案吗?

A:使用网络图片会有该限制,开发者可以将图片预置在resource中规避

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值