【问题分析】InputDispatcher无焦点窗口ANR问题【Android 14】

本文详细分析了Monkey操作导致的Android应用ANR问题,涉及无焦点窗口、InputDispatcher、FocusResolver等组件的工作原理,以及系统UI旋转对焦点处理的影响,最终揭示了recents_animation_input_consumer焦点丢失的深层次原因。

在这里插入图片描述

1 问题描述

Monkey跑出的无焦点窗口的ANR问题。

特点:

1)、上层WMS有焦点窗口,为Launcher。

2)、native层InputDispacher无焦点窗口,上层为”recents_animation_input_consumer“请求了焦点,但是”recents_animation_input_consumer“最终没有成为焦点窗口,原因是”NO_WINDOW“。

2 log分析

在这里插入图片描述

3 复现ANR

从log分析中可以看到发生ANR的场景的上下文:

1)、首先是SystemUI主线程比较卡顿的情况下,这种的我们要复现问题可能需要给SystemUI的绘制加点延迟。

2)、先启动了一个Activity,“com.tct.nxtvision_ui/.LauncherActivity”。

3)、随后屏幕转为了180度,即ROTATION_2。

4)、输入KeyEvent.KEYCODE_RECENT_APPS(312),切换到Launcher的Recents,并且屏幕转为0度,即ROTATION_0。

5)、接着在焦点App切换到Launcher之前,又输入了一个KeyEvent.KEYCODE_BACK(4),并且是第一步启动Activity接收到了,并且调用了finish —— KO!!!后续native层的InputDispacher出现了无焦点窗口的情况。

4 原因分析

4.1 NO_WINDOW代码分析

回到当时看log时,分析ANR出现的直接原因:

在这里插入图片描述

这里InputDispatcher侧的焦点窗口从“recents_animation_input_consumer”切走,直接原因为“NO_WINDOW”,查看到具体代码位置,FocusResolver.setInputWindows:

在这里插入图片描述

关键的地方有:

大概的内容为,局部变量currentFocus代表的是存储的焦点窗口,而windows代表的是从SurfaceFlinger处传入的最新的可接收输入事件的输入窗口列表,这里继续调用FocusResolver.getResolvedFocusWindow去寻找一个焦点窗口,并且调用FocusResolver.updateFocusedWindow来更新焦点窗口。

继续看FocusResolver.getResolvedFocusWindow:

在这里插入图片描述

这里的逻辑主要是调用FocusResolver.isTokenFocusable来判断某一个窗口是否能够作为焦点窗口:

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值