Android ANR分析实践(一):ANR是什么、产生的原因及如何避免ANR

  一、  什么是ANR

    ANR,(Application Not Responding) 即应用程序无响应,在android应用中,当我们的UI线程被阻塞,就会弹出如下对话框,用户可以选择继续等待或者关闭这个应用程序,这种现象我们称之为ANR.

二、  ANR的类型

ANR的类型大致分为以下三种

1、主线程对输入事件在5秒内没有处理完毕                                                                                                                                           产生这种ANR的前提是要有输入事件,如果用户没有触发任何输入事件,即便是主线程阻塞了,也不会产生ANR,因为InputDispatcher没有分发事件给应用程序,当然也不会检测处理超时和报告ANR了。

2、主线程在执行BroadcastReceiver的onReceive函数时10秒内没有执行完毕,后台进程是60秒                                                          这种情况的ANR系统不会显示对话框提示,仅是输出log而已。

3、主线程在执行Service的各个生命周期函数时20秒内没有执行完毕,后台进程为200秒
      同样对这种情况的ANR系统也不会显示对话框提示,仅是输出log。

三种类型的ANR只有第一种会有弹框。

Type

Method call

Log sample

time out

Input dispatch

onClick(),onTouch(),onKeydown(),onKeyup()

Input dispatching timed out

  5

Broadcast

onReceive()

Timeout of broadcast

FG: 10, BG 60

Service

onBind(),onCreate(),onStartCommand(),onUnbind(),onDestroy()

Timeout executing service

FG: 20, BG 200

三、  ANR产生的原因

大致分为两类:

1.应用自身进程引起的问题,比如, 在oncreate ,onstart等生命周期中执行耗时操作,ui线程阻塞,挂起,死循环等

2,其他进程引起的,比如:io操作导致cpu使用过高,导致当前应用进程无法抢占到cpu时间片

细分的话可以分为以下一些情况:

  • 耗时的网络访问
  • 大量的数据读写
  • 数据库操作
  • 硬件操作(比如camera)
  • 调用thread的join()方法、sleep()方法、wait()方法或者等待线程锁的时候
  • service binder的数量达到上限
  • system server中发生WatchDog ANR
  • service忙导致超时无响应
  • 其他线程持有锁,导致主线程等待超时
  • 其它线程终止或崩溃导致主线程一直等待...

四、如何避免ANR

  • 耗时的工作()比如数据库操作,I/O,网络操作),采用单独的工作线程处理
  • 用Handler来处理UIthread和工作thread的交互
  • 合理使用 Handler 来处理其他线程请求;
  • 合理使用并遵循 Android 生命周期, 避免在 onCreate() and onResume() 做过多的事情;
  • 使用一些架构形成规范来避免内存等问题,例如:MVP、RxJava;
  • 经常使用工具来检查内存问题,例如:MAT、TraceView、AS 自带等工具;
  • 避免加载大图片引起内存不足导致 ANR;
  • 避免内存泄露引起的 ANR。

猜你喜欢

转载自blog.csdn.net/pshiping2014/article/details/81740768