目录

如何定位并解决卡片白屏展示的问题

问题现象

在开发服务卡片功能时,可能会出现卡片白屏显示异常的问题。这可能是因为卡片页面样式配置错误,也可能是因为没有遵循卡片的开发约束。如何通过卡片日志定位并解决问题?异常示例图如下:

背景知识

问题定位

场景一:
08-30 23:13:10.652 6421 6421 W A01B01/com.ohos.sceneboard/HOME: FormItemRelativeEvent: event registration completed
08-30 23:13:10.652 6421 6421 I A01C05/com.ohos.sceneboard/FORM: FormComponentEvent: setFormOpacity, opacity: 0.005

根据日志信息进行定位,全局搜索关键词setFormOpacity定位,发现卡片透明度被设置为0.005(偏低),因此卡片的内容会呈现空白。

场景二:
[ecmascript] Pending exception before ExecutePendingJob called, in line:5868, exception details as follows:
TypeError: Cannot read property createHttp of undefined
Cannot get SourceMap info, dump raw stack: at anonymous (entry|myhar|1.0.0|src/main/ets/components/MainPage.ts:60:40)

出现“Cannot get SourceMap info, dump raw stack”关键字,通常表明开发者的API写法存在错误,或者引入了不支持卡片的模块,从而导致相关模块报错。若错误类型为“TypeError:Cannot read property xxx”,需首先确认该属性是否属于系统模块,并进一步明确当前模块是否支持服务卡片。以调用http模块中createHttp方法为例:根据错误日志,对报错文件中的属性进行检查,发现存在如下定义:

import { http } from '@kit.NetworkKit';
let httpRequest = http.createHttp();

点击函数声明,查询该函数是否支持在卡片中使用。

/**
  * Creates an HTTP request task.
  * @returns { HttpRequest } the HttpRequest of the createHttp.
  * @syscap SystemCapability.Communication.NetStack
  * @crossplatform
  * @atomicservice
  * @since 11
  */
function createHttp(): HttpRequest;

经查询,该函数缺少@form标签,即不支持在卡片中使用。

场景三:

[ecmascript] Pending exception before ExecutePendingJob called, in line:5868, exception details as follows:
TypeError: Cannot read property name of undefined
Cannot get SourceMap info, dump raw stack: at anonymous (entry|entry|1.0.0|src/main/ets/widget/pages/WidgetCard.ts:43:40)

出现“Cannot get SourceMap info, dump raw stack”关键字,通常表明代码中API写法存在错误,或者引入了不支持卡片的模块,从而导致相关模块报错。若错误类型为“TypeError:Cannot read property xxx”,需首先确认该属性是否属于业务变量。如果是业务变量,则由业务方自行规避。以访问空数组对象的属性为例:根据错误日志,对报错文件中的属性进行检查,发现存在如下定义:

interface Person {
  name: string;
  age: number;
}

let persons: Person[] = []
console.info(persons[0].name)

场景四:

[form_provider_data.cpp(AddImageData:154)]Get file size failed, errno is 0

在服务卡片的数据更新流程中,当通过FormExtensionAbility向卡片管理服务(FormManagerService, FMS)传递图片文件描述符(fd)时,系统底层模块检测到获取图片文件大小失败。此问题通常发生在卡片通过updateForm方法更新数据时,涉及内存图片(memory://fileName)的加载逻辑。根据系统设计,服务卡片在刷新图片时需依赖文件描述符(fd)从内存中读取图片数据并完成渲染。

场景五:

load SharedMemoryImage timeout!

在服务卡片的运行过程中,当通过共享内存(Shared Memory)方式加载图片时,系统底层触发了超时异常(load SharedMemoryImage timeout!)。此问题通常发生在卡片一次性请求加载大量网络图片的场景中,其根本原因与卡片对共享内存的资源限制密切相关——系统在处理图片数据时,需将图片加载到共享内存中完成渲染,若图片总量或单张图片大小超出限制,系统将无法及时完成加载,进而触发超时。

分析结论

场景一:

应用的卡片透明度设置偏低,导致卡片内容呈现空白。

场景二:

卡片中调用了不支持的系统模块,调用方式可能为直接调用或者通过引用包间接调用。

场景三:

卡片自定义业务中出现了异常,缺乏边界值或空值条件判断。

场景四:

异常的核心原因在于传递给卡片管理服务的图片文件描述符(fd)无效或指向的文件已被提前释放。

场景五:

从API version 20开始,系统对卡片刷新数据的共享内存总大小限制为10MB,且单次刷新的图片数量上限为20张。在API version 19及之前的版本中,限制更为严格:图片文件数量上限为5张,且每张图片的内存占用不得超过2MB。若开发者在FormExtensionAbility中传递的图片文件描述符(fd)所指向的图片总量或数量超出上述限制,则系统在尝试加载共享内存时会因资源不足而超时,最终导致图片显示异常或卡片渲染失败。

修改建议

场景一:

在WidgetCard.ets文件中开发UI界面时,将卡片的透明度(即opacity属性)设置为合理可见的值。

场景二:

删除不支持卡片的模块。

场景三:

在可能出现异常的业务代码中补充判断逻辑。

场景四:

  1. 确保文件存在:在调用fileio.openSync前,使用fileio.statSync(path)检查目标文件是否存在且可读。
  2. 异步加载同步化:对于网络图片(如通过网络下载后保存到内存),需确保图片完全下载并写入文件系统后再调用fileio.openSync获取fd。可通过@ohos.data.fileio模块的异步API(如downloadFile)结合Promise或async/await控制流程,避免因文件未写入完成导致fd无效。

场景五:

  1. 图片数据优化:通过Image kit相关接口,对图片进行压缩。对于非关键场景(如背景图、低优先级商品图),可采用有损压缩(如JPEG质量参数调整),减少内存占用;对于关键场景(如Logo、核心广告图),优先使用无损压缩(如WebP格式转换)以平衡质量与体积。
  2. 刷新策略调整,分批次更新:若业务需刷新多张图片(如超过20张或单张体积较大),应将图片更新请求拆分为多个批次。例如,首次刷新加载首屏关键图片(如轮播图、促销栏),后续通过监听用户交互(如滚动、下拉),逐步加载非首屏图片。

总结

问题现象

关键日志

问题根因

解决方案

卡片白屏

setFormOpacity

卡片透明度被设置较低,导致卡片内容空白

将卡片的透明度(即opacity属性)设置为合理可见的值。

Cannot get SourceMap info, dump raw stack

卡片页面直接/间接引入了不支持卡片的模块

在卡片使用带有@form标签的API

Cannot get SourceMap info, dump raw stack

自定义业务逻辑错误

根据实际业务修改

Get file size failed, errno is 0

图片还未完成加载就打开

图片加载完毕后再渲染

load SharedMemoryImage timeout!

图片大小超过共享内存最大限制

图片压缩

常见FAQ

Q:在卡片开发过程中,很多import方法以及UI能力的使用不支持服务卡片,但只有部分情况会在开发和编译构建时报错提示,体现为卡片显示白屏。如何进行问题定位?

A:当卡片的页面功能复杂时,可能在卡片的实际运行时才崩溃报错,体现为卡片显示白屏。(注意:一个卡片报错后会导致应用的所有卡片渲染全部挂掉成为白屏)出现此类情况时,可以在IDE中查看日志,选择com.ohos.formrenderservice卡片渲染服务查看error日志看具体卡片渲染报错原因。