Android ---【性能优化】都有哪些情况会发生anr,怎么解决?

Android ---【性能优化】都有哪些情况会发生anr,怎么解决?
前言Android发生ANR的情况主要包括输入调度超时、广播超时、服务超时等解决ANR问题的方法包括避免在主线程进行耗时操作、导出ANR日志信息、分析系统资源信息、查看主线程状态等。‌Android系统中ANRApplication Not Responding是一种自我保护措施当主线程出现卡顿时系统会给用户一个弹出提示让用户选择继续等待或强制关闭应用。一、ANR的发生通常与以下几种情况1.输入调度超时‌典型报错日志Input dispatching timedout(Waitingtosend non-key event because the touched window has not finished processing certain input events that were deliveredtoit earlier.Wait queue length:xx.Wait queue head age:xxxms)如果应用在5秒内未响应输入事件如按键或屏幕触摸就会发生ANR。这通常是由于主线程上的问题导致的如主线程上的阻塞操作或长时间等待获取锁。为了避免这种情况应避免在主线程上执行阻塞操作或长时间运行的操作并尽量减少主线程与其他线程之间的锁争用。原理讲解输入事件已经成功分发到了你的 App 的焦点窗口但主线程被耗时操作阻塞连续的触摸 / 滑动事件堆积在系统等待队列里主线程没法及时处理上一轮触摸事件队列堆积超时后系统判定应用输入无响应触发 ANR。常见诱因主线程做网络请求、大文件 IO、复杂布局渲染、同步数据库查询、死循环等耗时操作。2.广播超时‌典型报错日志Broadcast of Intent{actxxx flgxxx(has extras)}原理讲解广播接收器BroadcastReceiver的onReceive()运行在主线程系统对广播有严格超时限制普通静态广播onReceive()执行超过10 秒触发 ANR有序广播、前台广播超时阈值会更短。onReceive执行结束后系统就会回收接收器不能开子线程做耗时任务子线程也无法延长广播生命周期。常见诱因在onReceive里做本地数据库批量写入、同步网络请求、复杂文件处理或者频繁发送有序广播造成队列堆积。如果BroadcastReceiver的onReceive()方法执行时间超过规定阈值通常是10秒也会触发ANR。解决这一问题的方法包括优化广播接收器的逻辑确保其执行时间在可接受范围内。前台广播超时时间是10s,后台广播超时时间是60s。3.服务超时‌分两种场景的日志 说明1.前台 / 后台 Service 启动超时startService触发典型日志Timeout executing service:ServiceRecord{xxxx u0 xxx.xxx/.XXXService}规则onCreate()、onStartCommand()主线程执行超过20 秒触发 ANR。2.绑定 Service 超时bindService触发典型日志Timeout waitingforservice xxx.xxx/.XXXServicetoconnect规则onBind()主线程执行超过20 秒触发 ANR。原理讲解Service 生命周期全部运行在主线程如果你在onCreate/onStartCommand/onBind里写了大量同步耗时逻辑系统在规定时间内收不到 Service 就绪的回调就会判定超时 ANR。常见诱因Service 里直接做文件解压、批量数据迁移、同步网络请求、大量初始化逻辑。4.没有焦点窗口导致输入超时典型报错日志Reason:Input dispatching timedout(Application does not have a ffocused window)原理讲解Android 系统InputDispatcher负责把触摸、按键等输入事件分发到当前获得焦点的窗口你的 App 所有窗口Activity、Dialog、悬浮窗、插件弹窗等都没拿到系统焦点系统找不到输入事件的接收目标持续等待 5 秒默认超时阈值仍无可用焦点窗口触发 ANR。常见诱因悬浮窗 / 状态栏插件默认加了FLAG_NOT_FOCUSABLE禁止获取焦点、Activity 退到后台被其他应用抢占焦点、页面销毁后新窗口未完成焦点申请。二、解决ANR问题的方法导出ANR日志信息‌当ANR发生时系统会收集相关日志信息包括CPU使用情况、线程执行情况等这些信息可以帮助定位问题原因。分析系统资源信息‌关注CPU、内存、IO等系统资源的使用情况这些信息有助于判断ANR是否由系统资源争抢导致。查看主线程状态‌检查主线程是否存在耗时、死锁、等待锁等问题这些问题可能导致ANR。‌结合应用日志、代码或源码分析‌通过查看应用日志和代码可以分析ANR问题发生前应用是否有异常从而找到具体问题所在。如果你想快速定位就搜索main关键字然后看堆栈分析即可!!综上所述解决Android的ANR问题需要从避免在主线程进行耗时操作、优化代码逻辑、及时处理系统资源争抢等多个方面入手同时通过导出和分析ANR日志信息来定位和解决问题