一 问题说明
问题:26系统开会找不到 XXX窗口
是否必现:否
二 分析排查
1.窗口生命周期日志分析
结论:排除窗口位置因素,生命周期日志显示位置符合预期。
增加窗口生命周期位置与可见性相关的日志。可以确定:26系统的不可见,不存在业务问题,窗口位置与尺寸、可见性都是正常的。
级别:INFO
param:{"left":108.0,"top":109.25,"width":1224.0,"height":681.5,"minSize":{"width":450.0,"height":318.0},"center":true,"animate":false,"page":""}
级别:INFO
坐标: (83, 141), 大小: 1224x681 | 可见性: YES | 是否全屏: NO | 所在屏幕: 内建视网膜显示器 | 显示器个数: 2
分析流程【展示 XXX主窗口】--【设置窗口位置】---【系统回调窗口可见性与位置】,业务逻辑上是没有问题的。
2.利用辅助功能--抓取窗口属性
结论:抓取窗口的关键属性(尺寸、frame,),均是正常范围呢,未见异常。
针对同一窗口****1736,** **出问题时候 :
App Name: XXX
Window Name: 通话
Window Size: 1224 x 681
Button Name:
role=AXButton, attri=AXHelp, text=此按钮也可以执行缩放窗口的操作
Window Attribute:
AXFocused: NO
AXFullScreen: NO
AXTitle: 通话
AXChildrenInNavigationOrder: []
AXFrame: {{83, 78}, {1224, 681}} //Y坐标原点是屏幕顶部,向下为正
AXPosition: {83, 78}
AXMinimizeButton: AXUIElementRef
AXSections: []
AXCloseButton: AXUIElementRef
AXMain: NO
AXActivationPoint: {143, 92}
AXFullScreenButton: AXUIElementRef
AXMinimized: NO
AXChildren: []
AXRole: AXWindow
AXParent: AXUIElementRef
AXModal: NO
AXSubrole: AXStandardWindow
AXZoomButton: AXUIElementRef
AXRoleDescription: 标准窗口
AXSize: {1224, 681}
AXIdentifier: _NS:85
针对同一窗口****1736,** **问题恢复后 :
App Name: XXX
Window Name: 通话
Window Size: 1224 x 681
Button Name:
role=AXButton, attri=AXHelp, text=此按钮也可以执行缩放窗口的操作
Window Attribute:
AXFocused: NO
AXFullScreen: NO
AXTitle: 通话
AXChildrenInNavigationOrder: []
AXFrame: {{83, 78}, {1224, 681}} //Y坐标原点是屏幕顶部,向下为正
AXPosition: {83, 78}
AXMinimizeButton: AXUIElementRef
AXSections: []
AXCloseButton: AXUIElementRef
AXMain: NO
AXActivationPoint: {143, 92}
AXFullScreenButton: AXUIElementRef
AXMinimized: NO
AXChildren: []
AXRole: AXWindow
AXParent: AXUIElementRef
AXModal: NO
AXSubrole: AXStandardWindow
AXZoomButton: AXUIElementRef
AXRoleDescription: 标准窗口
AXSize: {1224, 681}
AXIdentifier: _NS:85
3.屏幕扫描-抓取窗口属性
截图显示:通过抓取的窗口的宽高与位置均是0。故可借助该手断,分析“窗口尺寸是否异常“,从而判定出现问题!!!
针对同一窗口****1736,** **出问题时候 :
无效应用(XXX), 详情:windowRect < 100,100, detail:{
kCGWindowAlpha = 1;
kCGWindowBounds = {
Height = 0;
Width = 0;
X = 0;
Y = 0;
};
kCGWindowIsOnscreen = 1;
kCGWindowLayer = 0;
kCGWindowMemoryUsage = 2368;
kCGWindowName = "通话";
kCGWindowNumber = 1736;
kCGWindowOwnerName = "XXX";
kCGWindowOwnerPID = 60634;
kCGWindowSharingState = 1;
kCGWindowStoreType = 1;
}
针对同一窗口****1736,** **问题恢复后 :
{
kCGWindowAlpha = 1;
kCGWindowBounds = {
Height = 681;
Width = 1224;
X = 83;
Y = 78; //Y坐标原点是屏幕顶部,向下为正
};
kCGWindowIsOnscreen = 1;
kCGWindowLayer = 0;
kCGWindowMemoryUsage = 2368;
kCGWindowName = "\U901a\U8bdd";
kCGWindowNumber = 1736;
kCGWindowOwnerName = "\U5982\U6d41";
kCGWindowOwnerPID = 60634;
kCGWindowSharingState = 1;
kCGWindowStoreType = 1;
},
三 解决方案
分析:XX窗口出问题为什么总是出现 “窗口不可见“现象,而竞品窗口不存在该问题。
本质还是该窗口关闭的时候,**本身并非真正销毁;而是考虑引擎复用,一直不销毁导致窗口,仅仅通过“设置窗口隐藏” **,实现关闭。每次入会展示窗口,不是创建新的,而是通过setAlphaValue 与 showWindow实现的。
1.关闭逻辑
本质还是该窗口关闭的时候,本身并非真正销毁;而是考虑引擎复用,一直不销毁导致窗口,仅仅通过“设置窗口隐藏”
[[self.window animator] setAlphaValue:0.0];
[self.window close];
2.展示逻辑
每次入会展示窗口,不是创建新的,而是通过setAlphaValue 与 showWindow实现的
if (!(self.window).visible && showVideoWindow) {
[self.window center];
}
[self.window makeKeyAndOrderFront:nil];
[self.window setAlphaValue:1.0];
[self showWindow:nil];
3.解决方案
1.埋点统计
本质因该问题非毕现,也不确定出问题后是否真正解决,故需要增加埋点统计
| 字段名 | 字段说明 | 字段取值 | 含义 |
|---|---|---|---|
| head.action | | common_event | 通用事件上报 |
| body.event | | detect_window_invisible | 事件名称 |
| body.params | kCGWindowBounds | string | 窗口kCGWindowBounds属性 |
| windowFrame | string | 窗口尺寸 | |
| ab_enabeld | bool | 是否在(auto_fix_window_invisible)名单中 | |
| auto_fixed | bool | 如果ab_enabeld是,是否自动恢复成功了 |
2.尝试兜底保护
考虑出问题之后,如果退出 XXX窗口,然后重新入会就可以恢复正常,故建议修复方案如下:
- 首先,可以通过kCGWindowBounds,进行判断窗口是否异常。如果异常,尝试二次设置窗口属性与尺寸。
- 其次,二次校准生效,则建议尝试销毁 XXX窗口,重新建立 XXX主窗口。
3.增加AB策略,控制风险
该问题为低概率触发Bug,但是由于改变窗口默认展示方式,为控制变更风险,避免引入潜在问题,通过 AB 配置进行功能开关控制,并计划逐步放量验证效果。
| key | auto_fix_window_invisible | | | AB饰演的名称 |
|---|---|---|---|---|
| content | enable | 1 | | 1 表示开启,0关闭 |