ANR的一些解决

在Android里, App的响应能力是由Activity Manager和Window Manager系统服务来监控的. 在主线程(UI线程)里面做了太多的阻塞耗时操作, 例如文件读写, 数据库读写, 网络查询等等.

ANR一般有三种类型
1. KeyDispatchTimeout(5 seconds) –主要是类型按键或触摸事件在特定时间内无响应
2. BroadcastTimeout(10 seconds) –BroadcastReceiver在特定时间内无法处理完成
3. ServiceTimeout(20 secends) –小概率事件 Service在特定的时间内无法处理完成

哪些操作会导致ANR 在主线程执行以下操作:
1. 高耗时的操作,如图像变换
2. 磁盘读写,数据库读写操作
3. 大量的创建新对象

3、如何避免
不要在主线程(UI线程)里面做繁重的操作.

  1. UI线程尽量只做跟UI相关的工作
  2. 耗时的操作(比如数据库操作,I/O,连接网络或者别的有可能阻塞UI线程的操作)把它放在单独的线程处理
  3. 尽量用Handler来处理UIThread和别的Thread之间的交互
    4、解决的逻辑
  4. 使用AsyncTask
    a. 在doInBackground()方法中执行耗时操作
    b. 在onPostExecuted()更新UI
  5. 使用Handler实现异步任务
    a. 在子线程中处理耗时操作
    b. 处理完成之后,通过handler.sendMessage()传递处理结果
    c. 在handler的handleMessage()方法中更新UI
    d. 或者使用handler.post()方法将消息放到Looper中

3.1 哪些地方是执行在主线程的
1. Activity的所有生命周期回调都是执行在主线程的.
2. Service默认是执行在主线程的.
3. BroadcastReceiver的onReceive回调是执行在主线程的.
4. 没有使用子线程的looper的Handler的handleMessage, post(Runnable)是执行在主线程的.
5. AsyncTask的回调中除了doInBackground, 其他都是执行在主线程的.
6. View的post(Runnable)是执行在主线程的.


● 主线程被IO操作(从4.0之后网络IO不允许在主线程中)阻塞。
● 主线程中存在耗时的计算
● 主线程中错误的操作,比如Thread.wait或者Thread.sleep等 Android系统会监控程序的响应状况,一旦出现下面两种情况,则弹出ANR对话框
● 应用在5秒内未响应用户的输入事件(如按键或者触摸)
● BroadcastReceiver未在10秒内完成相关的处理
● Service在特定的时间内无法处理完成 20秒
● 使用AsyncTask处理耗时IO操作。
● 使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认Thread的优先级和主线程相同。
● 使用Handler处理工作线程结果,而不是使用Thread.wait()或者Thread.sleep()来阻塞主线程。
● Activity的onCreate和onResume回调中尽量避免耗时的代码
● BroadcastReceiver中onReceive代码也要尽量减少耗时,建议使用IntentService处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值