
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来判断某一个窗口是否能够作为焦点窗口:


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

被折叠的 条评论
为什么被折叠?



