`

Android ANR (转)

 
阅读更多
1)什么引发了ANR?

在Android里,应用程序的响应性是由Activity Manager和WindowManager系统服务监视的。当它监测到以下情况中的一个时,Android就会针对特定的应用程序显示ANR:

在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)
BroadcastReceiver在10秒内没有执行完毕

一个ANR对话框显示给用户

2)如何避免ANR?

考虑上面的ANR定义,让我们来研究一下为什么它会在Android应用程序里发生和如何最佳构建应用程序来避免ANR。

Android应用程序通常是运行在一个单独的线程(例如,main)里。这意味着你的应用程序所做的事情如果在主线程里占用了太长的时间的话,就会引发ANR对话框,因为你的应用程序并没有给自己机会来处理输入事件或者Intent广播。


因此,运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建操作。潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者以数据库操作为例,通过异步请求的方式)来完成。然而,不是说你的主线程阻塞在那里等待子线程的完成——也不是调用Thread.wait()或是Thread.sleep()。替代的方法是,主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序,将能保证你的主线程保持对输入的响应性并能避免由于5秒输入事件的超时引发的ANR对话框。这种做法应该在其它显示UI的线程里效仿,因为它们都受相同的超时影响。

IntentReceiver执行时间的特殊限制意味着它应该做:在后台里做小的、琐碎的工作如保存设定或者注册一个Notification。和在主线程里调用的其它方法一样,应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不再是在子线程里做这些任务(因为BroadcastReceiver的生命周期短),替代的是,如果响应Intent广播需要执行一个耗时的动作的话,应用程序应该启动一个Service。顺便提及一句,你也应该避免在IntentReceiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广播时需要向用户展示什么,你应该使用Notification Manager来实现。


3)增强响应灵敏性

一般来说,在应用程序里,100到200ms是用户能感知阻滞的时间阈值。因此,这里有一些额外的技巧来避免ANR,并有助于让你的应用程序看起来有响应性。


如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度(ProgressBar和ProgressDialog对这种情况来说很有用)。
特别是游戏,在子线程里做移动的计算。
如果你的应用程序有一个耗时的初始化过程的话,考虑可以显示一个SplashScreen或者快速显示主画面并异步来填充这些信息。在这两种情况下,你都应该显示正在进行的进度,以免用户认为应用程序被冻结了。

15:59:37 I/ActivityManager(130): ANR in process: com.android.email(last in com.android.email)

=>frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
=>提示输出cpu信息

Annotation: keyDispatchingTimedOut
CPU usage:

=>frameworks\base\services\java\com\android\server\ProcessStats.java
=>输出cpu当前状态

=>/proc/loadavg 显示cpu负荷
=>1-分钟平均负载 / 5-分钟平均负载 / 15-分钟平均负载
Load: 4.37 /4.55 / 3.97
=>cpu状态的时间段
CPU usage from 10987ms to 27ms ago:

  =>/proc/state读取cpu的使用情况
=>http://linux.die.net/man/5/proc
  =>user
  =>kernel
  =>iowait
  =>irq ->0
  =>softirq ->0
  =>minor

  The number of minor faults the process has madewhich have not required loading a memory page fromdisk.

  =>major

  The number of major faults the process has madewhich have required loading a memory page from disk.
  system_server: 12% = 4% user + 7% kernel /faults: 1886 minor
  m.android.email: 12% = 6% user + 5% kernel /faults: 2716 minor
  sensorserver_ya: 7% = 0% user + 7%kernel
  breeze.launcher: 3% = 0% user + 3% kernel /faults: 94 minor
  ocess.msn.shell: 0% = 0% user + 0% kernel /faults: 38 minor
  m.android.phone: 0% = 0% user + 0%kernel
  alog: 0% = 0% user + 0% kernel
  rpcrotuer_smd_x: 0% = 0% user + 0%kernel
  rild: 0% = 0% user + 0% kernel
  alog: 0% = 0% user + 0% kernel
  events/0: 0% = 0% user + 0% kernel
  port-bridge: 0% = 0% user + 0% kernel
TOTAL: 81% = 13% user + 25% kernel + 42% iowait


15:59:37 I/ActivityManager(130): Removing old ANR trace file from/data/anr/traces.txt

Android ANR这个错误大家并不陌生,但是从Android2.2开始出错的ANR信息会自动上传给Google进行系统分析改进,当然了你的应用ANR错误其实保存在一个文件中,在/data/anr/traces.txt文件中.
下面一起来分析下错误吧,第一行为出错的时间,第二行都会写上发生ANR的packageName,下文是com.android.systemui这个包,里面的部分线程出了问题,通过下面的的xxx方法以及对应的java文件,后面的数字为xxx.java文件的第几行,是不是很方便呢?
----- pid 125 at 2011-02-22 05:18:01 -----
Cmd line: com.android.systemui

DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x4001f1a8self=0xce48
  | sysTid=125 nice=0 sched=0/0 cgrp=defaulthandle=-1345006528
  | schedstat=( 981213067 8042604425 151 )
  at android.os.BinderProxy.transact(NativeMethod)
  atandroid.os.storage.IMountService$Stub$Proxy.isUsbMassStorageConnected(IMountService.java:95)
  atandroid.os.storage.StorageManager.isUsbMassStorageConnected(StorageManager.java:385)
  atcom.android.systemui.usb.StorageNotification.<init>(StorageNotification.java:71)
  atcom.android.systemui.statusbar.policy.StatusBarPolicy.<init>(StatusBarPolicy.java:412)
  atcom.android.systemui.statusbar.StatusBarService.onCreate(StatusBarService.java:239)
  atandroid.app.ActivityThread.handleCreateService(ActivityThread.java:1920)
  atandroid.app.ActivityThread.access$2500(ActivityThread.java:117)
  atandroid.app.ActivityThread$H.handleMessage(ActivityThread.java:982)
  atandroid.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:123)
  atandroid.app.ActivityThread.main(ActivityThread.java:3647)
  at java.lang.reflect.Method.invokeNative(NativeMethod)
  atjava.lang.reflect.Method.invoke(Method.java:507)
  atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
  atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
  at dalvik.system.NativeStart.main(NativeMethod)

"Binder Thread #2" prio=5 tid=8 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x40511270self=0x1c1100
  | sysTid=153 nice=0 sched=0/0 cgrp=defaulthandle=1141608
  | schedstat=( 27181321 64708345 5 )
  at dalvik.system.NativeStart.run(NativeMethod)

"Binder Thread #1" prio=5 tid=7 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x405111a8self=0x1349c8
  | sysTid=152 nice=0 sched=0/0 cgrp=defaulthandle=1264008
  | schedstat=( 31857510 74284459 5 )
  at dalvik.system.NativeStart.run(NativeMethod)

"Compiler" daemon prio=5 tid=6 VMWAIT
  | group="system" sCount=1 dsCount=0obj=0x4050dd10 self=0x116538
  | sysTid=144 nice=0 sched=0/0 cgrp=defaulthandle=982520
  | schedstat=( 7319346 103454345 12 )
  at dalvik.system.NativeStart.run(NativeMethod)

"JDWP" daemon prio=5 tid=5 VMWAIT
  | group="system" sCount=1 dsCount=0obj=0x4050dc60 self=0x116400
  | sysTid=142 nice=0 sched=0/0 cgrp=defaulthandle=986536
  | schedstat=( 32876840 393298925 20 )
  at dalvik.system.NativeStart.run(NativeMethod)

"Signal Catcher" daemon prio=5 tid=4 RUNNABLE
  | group="system" sCount=0 dsCount=0obj=0x4050dba0 self=0x253ab0
  | sysTid=141 nice=0 sched=0/0 cgrp=defaulthandle=2439792
  | schedstat=( 94447996 796994478 19 )
  at dalvik.system.NativeStart.run(NativeMethod)

"GC" daemon prio=5 tid=3 VMWAIT
  | group="system" sCount=1 dsCount=0obj=0x4050daf8 self=0x8fd40
  | sysTid=128 nice=0 sched=0/0 cgrp=defaulthandle=2439592
  | schedstat=( 103352102 819201761 21 )
  at dalvik.system.NativeStart.run(NativeMethod)

"HeapWorker" daemon prio=5 tid=2 VMWAIT
  | group="system" sCount=1 dsCount=0obj=0x4050da40 self=0xf0c70
  | sysTid=127 nice=0 sched=0/0 cgrp=defaulthandle=2439528
  | schedstat=( 971134410 6445300652 103 )
  at dalvik.system.NativeStart.run(NativeMethod)
分享到:
评论

相关推荐

    Android-ANR-WatchDog一个用于检测AndroidANR(应用不响应)的watchdog

    在Android应用开发中,ANR(Application Not Responding)是一个常见的问题,表示用户界面无响应,这通常是由于主线程被长时间阻塞导致的。`Android-ANR-WatchDog`是一个专门为解决这个问题而设计的开源工具,它能够...

    android anr

    Android ANR,全称为"Application Not Responding",是Android操作系统中的一种错误状态,提示用户应用程序无响应。当一个应用程序在主线程上执行的操作超过了5秒钟而没有完成时,系统会认为该应用出现ANR问题,并弹...

    通过Android trace文件分析死锁ANR实例过程

    在Android开发过程中,Application Not Responding(ANR)是一个开发者经常遇到的问题,它表示应用程序对用户操作或系统服务请求反应过慢,导致用户体验下降。ANR的产生原因多种多样,其中包括CPU负载过高、输入事件...

    Android ANR文件

    Android ANR文件,用于对ANR分析的例子文件

    android7 关闭ANR对话框代码

    在Android系统中,ANR(Application Not Responding)是一个常见的问题,它表示应用程序无响应,通常出现在用户界面长时间无法交互时。在Android 7.0版本中,框架引入了一种新特性,即自动关闭ANR对话框,并允许...

    如何分析及避免Android ANR问题.pdf

    ANR(Application Not Responding)问题是Android应用开发者经常会遇到的问题,尤其对于初学者来说,解决这类问题往往比较棘手。ANR问题通常发生在Android应用无法在规定时间内响应输入事件或广播消息时,导致系统弹...

    我的总结--Android之ANR的原理(Input, Service, Broadcast)

    ### Android之ANR的原理(Input, Service, Broadcast) #### ANR概述 ANR(Application Not Responding)是指Android应用程序在执行过程中响应超时的一种异常状态。当应用程序长时间不响应用户的操作时,系统会提示...

    android anr分析方法

    ANR,全称为Application Not Responding,是Android系统中一种重要的异常情况,表明用户界面无法正常响应用户的操作。当应用程序在指定时间内无法处理按键、触摸事件、BroadcastReceiver或Service时,系统会检测到...

    android anr分析.docx

    Android ANR 分析 ANR(Application Not Responding)是 Android 中的一个错误状态,当应用程序在 5 秒内没有响应输入事件或 BroadcastReceiver 在 10 秒内没有执行完毕时,Android 就会针对特定的应用程序显示 ANR...

    Android异常捕获demo(可以捕获ANR+UncaughtExceptionHandler)

    `Android异常捕获demo`主要展示了如何有效地捕获和处理两种重要的错误类型:应用程序无响应(ANR)和未捕获异常(UncaughtExceptionHandler)。下面我们将深入探讨这两个概念以及如何在实际应用中实现它们。 1. **...

    浅谈Android ANR在线监控原理

    浅谈Android ANR在线监控原理 Android ANR在线监控原理是指Android操作系统中对Application Not Responding(ANR)的在线监控机制。ANR是一种常见的Android应用程序错误,发生在应用程序线程中执行时间过长,导致...

    ANR代码流程分析.doc.tar.gz_ANR分析_android_anr代码_shp

    在Android系统中,ANR(Application Not Responding)是指应用程序无响应的错误,通常发生在用户界面线程上,导致用户无法进行任何操作。本文档"ANR代码流程分析.doc"将深入探讨ANR的产生原因及其相关的代码流程,这...

    Android图片压缩解决方案,解决图片加载过程中ANR现象

    在Android应用开发中,图片加载是常见的操作,但由于图片文件大小不一,如果处理不当,可能会导致内存溢出(OOM)或应用程序无响应(ANR)等问题。本解决方案旨在探讨如何有效压缩Android中的图片,避免ANR现象,...

    Android ANR详细介绍以及案例分析

    Android ANR详细介绍以及案例分析,对理解ANR具体原理有说明,并且列举大量实例解决实际问题,不可多得的稳定性文档。

    ANR-WatchDog:一个简单的看门狗,可检测到Android ANR(应用程序无响应)错误并引发有意义的异常

    看门狗一个简单的看门狗,可检测Android ANR(应用程序无响应)。目录 阅读ANRError异常报告配置超时(ANR的最小挂起时间) 调试器在ANR回调上过滤报告看门狗线程捐 为什么存在目前,Android应用程序无法捕获和报告...

    Android ANR(Application Not Responding)的分析

    Android ANR(Application Not Responding)的分析 ANR (Application Not Responding)   ANR定义:在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无...

    android ANR

    该文档主要介绍什么是anr, anr的三种类型,三种类型的具体分析,如何避免anr等等。。

    Android性能优化 ANR 问题分析

    Android性能优化 ANR 问题分析

Global site tag (gtag.js) - Google Analytics