UI上下文异常调试
本指导主要介绍如何解决因使用无效的UIContext导致文本显示异常的问题。当开发者使用了已失效的UIContext对象(通常是因为对应的UI实例已被销毁),可能导致后续UI操作无效。此类问题常见于多窗口场景。从API version 12开始,该问题也见于调用setSupportedProcessCache打开进程缓存后快速启动的情形。
定位UIContext错误问题
出现以下异常或系统日志时,可能存在UIContext无效的问题:
-
存在JS异常:"Node Constructor error, param uiContext error"。
产生该异常的原因通常是在自定义节点中使用了无效的UIContext,这可能导致后续UI操作被错误关联到该无效UIContext。
-
存在实例状态更新时,上下文实例ID大于等于100000且小于1000000的日志:
实例状态更新的日志格式为:
({currentId}:{trackedId}:{trackedReason})][{bundleName}][{moduleName}][{thisInstanceId}]: window {status}各字段含义为:
表1 实例状态更新日志字段含义
字段名 类型 典型值 说明 {currentId} 整数 -1 上下文实例ID,应用正常的情况下,该字段应该为负数。 {trackedId} 整数 100000 当前可间接跟踪的实例ID,通常为正数,开发者可忽略。 {trackedReason} 字符串 singleton 间接跟踪的原因,开发者可不关注该字段。 {bundleName} 字符串 com.example.helloworld 应用的bundleName。 {moduleName} 字符串 entry 当前模块的moduleName。 {thisInstanceId} 正数 100000 被通知UI实例的ID。 {status} 实例被通知的状态 focus 可选值为:
- focus:获焦
- unfocus:失焦
- foreground:前台
- background:后台
- destroy:销毁可使用如下正则表达式匹配相关日志:
\(-?\d+:-?\d+:(scope|active|default|singleton|foreground|undefined)\)\] \[[a-z0-9.]+\]\[[a-zA-Z][0-9a-zA-Z_.]*\]\[\d+\]: window (focus|unfocus|foreground|background|destroy)示例说明
-
正确日志示例:
(-2:100000:singleton)] [com.example.helloworld][entry][100000]: window foreground -
异常日志示例:
(100000:100000:scoped)] [com.example.helloworld][entry][100001]: window background该异常日志说明存在错误跟踪ID为100000的UI实例。
-
若前文出现以下特定格式的日志:
(-2:100000:singleton)] [com.example.helloworld][entry][100000]: window destroy表示ID为100000的UI实例已销毁,后续UI操作可能受其上下文影响。
-
实例详细信息
某些实例相关接口的报错信息会包含对应实例的信息,仅有缓存列表中的实例会输出详细信息。缓存列表仅保存被销毁的实例的信息。
说明:
- 当前缓存列表大小为10,采用LRU(最近最少使用)机制进行淘汰。
缓存命中
异常实例命中缓存时,详细信息的输出格式如下:
DestroyedUIContextCacheInfo: instanceInfo: [instanceId:<instanceId_>, createTime:<createTime_>, destroyTime:<destroyTime_>], windowInfo: [windowId: <windowId_>, windowName: <windowName_>]
缓存未命中
当请求的实例在缓存中不存在(从未被缓存、或已因超出缓存大小被移除)时,详细信息的输出格式如下:
InstanceId not found in destroyed cache.
完整消息示例
被缓存的已销毁的实例详细信息按照如下格式进行输出,包括实例ID、创建时间、销毁时间、窗口ID、窗口名称字段:
UI execution context not found.InstanceId: 100001,
Reason to get the instance: The instance is determined by the caller,
DestroyedUIContextCacheInfo: instanceInfo: [instanceId:100001, createTime:2026-04-14 10:30:00.123, destroyTime:2026-04-14 10:35:22.456], windowInfo: [windowId: 1001, windowName: EntryAbility]
消息中各字段含义如下:
instanceId:100001:表示请求的是100001号实例。Reason to get the instance: The instance is determined by the caller:表示由调用方显式指定了实例ID。createTime:2026-04-14 10:30:00.123:表示该实例创建时间为2026-04-14 10:30。destroyTime:2026-04-14 10:35:22.456:表示该实例销毁时间为2026-04-14 10:35,存活了约5分22秒。windowId: 1001:表示该实例关联窗口ID为1001。windowName: EntryAbility:表示该实例关联窗口名为EntryAbility。
表2 完整消息字段含义说明
| 属性 | 说明 |
|---|---|
| instanceId | 实例ID。由系统在创建实例时分配。 |
| Reason to get the instance | 获得对应实例的原因,详见表3实例指定原因说明。 |
| createTime | 实例创建的时刻。 |
| destroyTime | 实例销毁的时刻。 |
| windowId | 实例对应的窗口的ID。 |
| windowName | 实例对应的窗口的名称。 |
表3 实例指定原因说明
| 描述 | 说明 |
|---|---|
| The instance is determined by the caller. | 在调用过程中显式指定了实例ID。应用侧通常是通过UIContext接口进行指定。 |
| No specific instance was specified, so the most recently active instance was retrieved. | 未显式指定实例ID,系统返回最近活跃的实例。 |
| No specific instance was specified, return the foreground instance. | 未显式指定实例ID,系统返回前台实例。 |
| No specific instance was specified, return the only remaining instance. | 未显式指定实例ID,系统返回唯一的实例(仅存在一个UI实例时)。 |
| No specific instance was specified, using default. | 未显式指定实例ID,使用默认实例(最后创建的实例)。 |
| No valid instance exists. | 不存在有效的UI实例。 |
解决UIContext错误导致的显示异常问题
问题现象
当发生以下问题时,可根据上文的关键日志或异常进行判断:
- 使用setStyledString方法设置字体大小时,字体大小未发生预期变化。
- 使用UIContext成员方法时,界面没有响应或显示异常。
解决措施
重新获取有效的UIContext对象。可通过以下方式获取:
- 使用自定义组件的getUIContext方法获取。
- 通过窗口的getUIContext方法获取。