没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
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\ActivityManagerS
ervice.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(IMoun
tService.java:95)
atandroid.os.storage.StorageManager.isUsbMassStorageConnected(StorageManager.
java:385)
atcom.android.systemui.usb.StorageNotification.<init>(StorageNotification.jav
a:71)
atcom.android.systemui.statusbar.policy.StatusBarPolicy.<init>(StatusBarPolic
y.java:412)
atcom.android.systemui.statusbar.StatusBarService.onCreate(StatusBarService.j
ava:239)
atandroid.app.ActivityThread.handleCreateService(ActivityThread.java:1920)
atandroid.app.ActivityThread.access$2500(ActivityThread.java:117)
atandroid.app.ActivityThread$H.handleMessage(ActivityThread.java:982)
剩余14页未读,继续阅读
资源评论
川峰
- 粉丝: 1346
- 资源: 34
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功