news 2026/4/18 14:09:18

ANR高级经验分享:No Focused类型ANR详细步骤

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ANR高级经验分享:No Focused类型ANR详细步骤

文章目录

    • 背景
    • Not have a Focused Window介绍
    • 分析这类no Foucsed ANR技巧分享
      • **1、区分FocusedApplication和FocusedWindow**
        • FocusedApplication
        • FocusedWindow
    • 2 分析日志和dumpsys部分
        • events日志分析部分
        • dumpsys SF中焦点窗口显示情况
        • dumpsys window中焦点窗口是否计算正常
        • 检查应用生命周期,看是窗口否显示
        • 检查其他性能卡顿相关日志

背景

在马哥的wms实战课程中已经详细给大家讲解过Focused Window相关的知识,同时教大家详细分析了Not have a Focused Window这个类型的ANR相关案例。

但是在实际系统fw开发工作中,app层面报出的No Focused Window类型的ANR其实非常非常多,而且每一个ANR都可能情况不一样,所以针对这类 no Focused Window类型的ANR问题,用本文我们进行相关的一些相关于分析技巧总结归纳,大家以后分析都按照这个固定套路去分析哈。

Not have a Focused Window介绍

ANR是Android稳定性问题分析的一个难点,其中比较常见的一种是窗口无焦点Not have a Focused Window,这类无焦点窗口ANR相比其他Application not response无响应更难分析。

focused ANR一定是wms问题?

如果对该ANR的原理不了解,会直接认为窗口焦点是WMS控制,出现无焦点就一定是WMS导致。
其实不是这样哈,这种无焦点窗口ANR还是需要从ANR产生原理触发,结合系统相关日志,dumpsys等综合分析,才可以得出初步结论原因,也就是并不是这种no focused anr就是wms逻辑错误导致无焦点的,大部分情况下其实是属于系统某些卡顿,性能,或者app不正确操作设置等导致的,真正说wms自身逻辑错误导致no focused window其实还是很少哈。

所以当app产生这类no focused window的anr大家不要着急甩锅给系统wms负责的哈,应该自己学会来综合分析,不然很有可能很快甩锅回来。

无焦点ANR产生条件

无焦点类型的ANR不是所有输入事件都会触发。
在需要焦点窗口的input事件派发时,会去寻找焦点窗口,找不到的时候,会超时计时,过了超时时间,触发ANR
因此只有Key事件,和非触摸的Motion事件(比如滚轮),这种需要焦点窗口的,才会导致该类ANR。
所以大家在分析日志时候就会发现,一般只有key事件(包括实体按键和导航栏那种按钮模拟key事件)要派发才会有这类anr,只是手指触摸一般没有这类anr问题。

分析这类no Foucsed ANR技巧分享

其实针对这类anr问题,已经在wms实战课程中有给大家讲解过相关的案例分析,这里再进行总结归纳一下,方便大家记忆回顾课程。

1、区分FocusedApplication和FocusedWindow

FocusedApplication

FocusedApplication——对应Activity
FocusedWindow——对应窗口,但不一定是上述Activity的窗口。比如,在launcher上下拉状态栏,两者并不一致

FocusedApplications:displayId=0,name='ActivityRecord{173024276 u0 com.android.launcher3/.uioverrides.QuickstepLauncher t20}',dispatchingTimeout=5000ms FocusedWindows:displayId=0,name='7556327 NotificationShade'

FocusedApp是WMS通过JNI向InputDispatcher设置的,需要改变FocusedApp的地方不少,特殊场景是Activity在Display/Task间切换,比如:
resumeTopActivity,moveTaskToFront等方法。
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

*/booleansetFocusedApp(ActivityRecord newFocus){if(newFocus!=null){finalDisplayContent appDisplay=newFocus.getDisplayContent();// Called even if the focused app is not changed in case the app is moved to a different// TaskDisplayArea.onLastFocusedTaskDisplayAreaChanged(newFocus.getDisplayArea());}if(mFocusedApp==newFocus){returnfalse;}ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,"setFocusedApp %s displayId=%d Callers=%s",newFocus,getDisplayId(),Debug.getCallers(4));finalTask oldTask=mFocusedApp!=null?mFocusedApp.getTask():null;finalTask newTask=newFocus!=null?newFocus.getTask():null;mFocusedApp=newFocus;if(oldTask!=newTask){if(oldTask!=null)oldTask.onAppFocusChanged(false);if(newTask!=null)newTask.onAppFocusChanged(true);}getInputMonitor().setFocusedAppLw(newFocus);returntrue;}

这里也有对应的proto日志,大家可以考虑开放WM_DEBUG_FOCUS_LIGHT这个Proto的TAG。
当然也可以通过dumpsys window ,或者dumpsys input查看当前的FocusApp。

FocusedWindow

FocusedWindow是由WMS计算出一个焦点窗口(每个Display有自己的),将它传给SurfaceFlinger处理之后,再向InputDispatcher设置的。
早期的Android版本,WMS是直接向InputDispatcher设置的,现在传给SF处理,可能是考虑到窗口最终是否显示,是由SF决定的,这样更准确。

因此,WMS中计算出的焦点窗口,如果在SurfaceFlinger处理后处于非显示状态(被遮挡?),那么在InputDispatcher中,它是不能成为焦点窗口的。

因为在SF和Input需要进一步处理,所以WMS进行数据传递时,传递两种数据:
1、焦点窗口
2、各个窗口的信息

2 分析日志和dumpsys部分

events日志分析部分

定位anr问时间点:

adb logcat -b events|grepanr

一般会有am_anr打印,在这个日志的时间点前面开始找对应的input_focus相关日志。

focus相关日志

使用如下命令对focus相关切换进行跟踪

adb logcat -b events|grepinput

得到如下结果

01-2711:43:42.634718743I input_focus:[Focus request 20c1a6e com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher,reason=UpdateInputWindows]01-2711:43:42.654718828I input_focus:[Focus leaving7556327NotificationShade,reason=setFocusedWindow]01-2711:43:42.654718828I input_focus:[Focus entering 20c1a6e com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher,reason=setFocusedWindow]

request只是代表了请求焦点,entering才是代表真正在inputdispatcher层面获取焦点,所以很多anr情况都是有request请求焦点打印,但是没有对应的entering打印,这时候就可以确定大概anr的时间范围,然后在这个时间范围内进行dumpsys SF等窗口。

dumpsys SF中焦点窗口显示情况

在第二步确定大概anr的时间区间后进行dumpsys SurfaceFlinger看看对应的Layer信息
上面这种是正常情况下有焦点的,可以看到右边Focused Window有打上 * ,如果都没有一个 * 那就需要查看对应的Layer情况。

这种一般排查方向就是看看这个window是否真的在sf中显示正常,大小,遮盖,或者直接layer没有显示等情况,一般都是sf可以得出layer情况,从而anr得出直接原因,但是根本原因的话就需要根据具体layer情况进一步分析。

dumpsys window中焦点窗口是否计算正常

具体命令

adb shell dumpsys window|grep Focus-C5

正常可以看到如下结果

如果这里都不正常那么就需要查看wms部分的焦点窗口FocusedWindow的计算逻辑,放开对应的日志排查,排除方向在WMS。

检查应用生命周期,看是窗口否显示

adb logcat -b events | grep wm_on
主要看看对应的app的生命周期是否正常等,最重要还得看看wm_on_resume时间是不是延迟了,因为app自身一直没有执行导致的窗口没有显示等。

检查其他性能卡顿相关日志

adb logcat -b all | grep Slow
看看是否有自身进程相关慢处理日志,主要是定位窗口显示慢原因
原文地址
https://mp.weixin.qq.com/s/oYWumjZg8gEV_zybsAEwGA

更多framework实战开发干货资料,请关注下面“千里马学框架”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:27:18

AI+物联网赋能 健康有益重构企业健康服务模式

随着社会对心理健康、慢病防控及工作生活质量的关注度攀升,企业员工健康建设已从福利配套升级为组织可持续发展的核心要素。传统健康管理依赖年度体检、单次健康讲座等形式,存在数据孤岛化、干预碎片化、反馈机制缺失等痛点,重检测、轻管理的…

作者头像 李华
网站建设 2026/4/18 3:29:11

基板平整度:光子器件的光路稳定关键

“张经理,我们的激光器又烧驱动板了!”深夜接到客户的紧急电话。第二天看到那块焦黑的控制板时,我立刻明白问题所在:峰值电流200A的激光二极管,使用的却是普通2盎司铜厚PCB。电流密度超过设计极限五倍,铜箔…

作者头像 李华
网站建设 2026/4/17 14:22:01

GNSS监测仪 GNSS位移监测系统

Q1:GNSS监测仪的核心定位是什么?为何适配全场景工程结构安全监测?A:核心定位是“工程结构位移精准监测与灾害预警专用设备”,专注解决传统监测“精度低、响应慢、覆盖窄、自动化弱”的痛点,聚焦滑坡体、大坝…

作者头像 李华
网站建设 2026/4/18 1:58:38

学习笔记——LCD技术详解

LCD技术详解1. 核心定义与基本原理定义:LCD(Liquid Crystal Display,液晶显示器)是一种利用液晶的光电效应,通过控制光源透射率来实现显示的平板显示器。核心特性:液晶本身不发光,其作为“光阀”…

作者头像 李华