ANR

ANR的全称是application not responding,意思就是程序未响应,类似于我们在windows上见到的程序未响应。ANR发生会使用户觉得我们的程序不友好,那么什么情况会导致ANR的发生呢?

首先ANR的发生是有条件限制的,分为以下三点:

1.只有主线程才会产生ANR,主线程就是UI线程;

2.必须发生某些输入事件或特定操作,比如按键或触屏等输入事件,在BroadcastReceiver或Service的各个生命周期调用函数;

3.上述事件响应超时,不同的context规定的上限时间不同

    a.主线程对输入事件5秒内没有处理完毕

    b.主线程在执行BroadcastReceiver的onReceive()函数时10秒内没有处理完毕

    c.主线程在Service的各个生命周期函数时20秒内没有处理完毕。

那么导致ANR的根本原因是什么呢?简单的总结有以下两点:

1.主线程执行了耗时操作,比如数据库操作或网络编程

2.其他进程(就是其他程序)占用CPU导致本进程得不到CPU时间片,比如其他进程的频繁读写操作可能会导致这个问题。

细分的话,导致ANR的原因有如下几点:

1.耗时的网络访问

2.大量的数据读写

3.数据库操作

4.硬件操作(比如camera)

5.调用thread的join()方法、sleep()方法、wait()方法或者等待线程锁的时候

6.service binder的数量达到上限

7.system server中发生WatchDog ANR

8.service忙导致超时无响应

9.其他线程持有锁,导致主线程等待超时

10.其它线程终止或崩溃导致主线程一直等待

那么如何避免ANR的发生呢或者说ANR的解决办法是什么呢?

1、运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建操作。(可以采用重新开启子线程的方式,然后使用Handler+Message的方式做一些操作,比如更新主线程中的ui等)

2、应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不再是在子线程里做这些任务(因为BroadcastReceiver的生命周期短),替代的是,如果响应Intent广播需要执行一个耗时的动作的话,应用程序应该启动一个Service。(此处需要注意的是可以在广播接受者中启动Service,但是却不可以在Service中启动broadcasereciver,关于原因后续会有介绍,此处不是本文重点)

3、避免在IntentReceiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广播时需要向用户展示什么,你应该使用Notification Manager来实现。

链接:http://www.jianshu.com/p/7fd95bc2a55c
### ANR (Application Not Responding) 原因及解决方法 #### 主要成因 ANR现象主要发生在应用程序用户界面(UI)线程未能在规定时间内完成特定任务的情况下。具体来说: - **按键或触摸事件**:如果这些交互事件超过5秒未被处理,就会触发ANR警告[^1]。 - **BroadcastReceiver组件**:当此类组件接收广播消息后的执行时间超过了10秒钟,则会引发ANR提示。 - **Service服务调用**:对于长时间运行的服务,在其首次创建时若花费的时间超出20秒也会导致ANR情况的发生。 上述情形通常是因为当前正在处理的任务要么完全没有得到机会被执行,要么虽然已经开始但因为计算量过大或其他因素而未能迅速结束[^3]。 #### 导致ANR的具体场景 除了以上提到的时间限制外,还有几种常见的情况可能导致ANR: - 进行复杂的图形渲染或者大量的DOM操作; - 执行网络请求、文件读写等I/O密集型工作; - 处理大规模数据集或是进行深度嵌套循环等高负载CPU运算; - 错误地将耗时较长的操作放在了主线程中而是异步方式下进行; 这些问题都可能使得UI线程陷入忙碌状态,从而影响到整个应用对外界输入做出即时反馈的能力[^4]。 #### 解决方案建议 为了避免ANR问题并提高用户体验质量,可以采取如下措施来优化代码逻辑和架构设计: - 将任何潜在的大规模计算移至后台线程(如通过`AsyncTask`, `Thread`, 或者使用更现代的选择如Kotlin协程),确保会阻塞主线程; ```kotlin CoroutineScope(Dispatchers.IO).launch { // 耗时操作... } ``` - 对于需要频繁更新UI的内容,考虑采用分页加载策略减少一次性展示的数据量; - 使用高效算法代替低效实现以加快处理速度; - 定期监控性能指标并通过工具链诊断瓶颈所在位置以便针对性改进; - 利用Logcat记录详细的调试信息帮助定位实际发生的错误点,并据此调整业务流程使之更加流畅稳定[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值