一.概述
ANR使我们日常开发中偶尔会遇到的一种情况,也就是应用程序无响应,其实在应用出现ANR的时候,系统会在控制台给出错误提示,并且会产生一个相关的日志文件,今天我们就来分析一下。
二.分析
首先我们要模拟一个ANR现象,很简单,下面的代码就可以实现,
public void click(View view){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我们在按钮的点击事件里面让主线程休眠足够的时间,这里设为10秒,点击按钮后,我们继续不停的点击屏幕,很快就会出现ANR现象,这时候就产生了一个文件,那么这个文件在哪里呢?在data/anr文件下,文件的名称是traces.txt。在这之前我们先看看控制台的错误信息
已经提示我们ANR在哪个文件里面出现了。
接下来该看看日志文件了,在这之前我先讲讲什么时候系统会产生日志文件
1,程序异常退出,uncausedexception (Fatal)
2,程序强制关闭,ForceClosed (简称FC) (Fatal)
3,程序无响应,ApplicationNo Response(简称ANR)
ANR出现的情况有以下两种
A 界面操作按钮的点击等待响应时间超过5秒
B HandleMessage回调函数执行超过10秒,BroadcasterReciver里的onRecive()方法处理超过10秒
这时候我们来看系统产生的日志,在data/anr目录下的traces.txt,
----- pid 1761 at 2016-03-10 06:16:34 -----
Cmd line: com.example.activityandservice
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 TIMED_WAIT
| group="main" sCount=1 dsCount=0 obj=0xb5d33938 self=0xb9295e80
| sysTid=1761 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1208127328
| state=S schedstat=( 0 0 0 ) utm=2 stm=17 core=0
at java.lang.VMThread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:1031)
at java.lang.Thread.sleep(Thread.java:1013)
at com.example.activityandservice.MainActivity.click(MainActivity.java:25)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at android.view.View$1.onClick(View.java:3592)
at android.view.View.performClick(View.java:4202)
at android.view.View$PerformClick.run(View.java:17340)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
这个文件里面保存的是虚拟机信息,我们在这只给出了tid为1也就是主线程的信息,然后我们就看到这样一条信息
at com.example.activityandservice.MainActivity.click(MainActivity.java:25)
于是我们定位到代码
我们看到就是因为25线程休眠时间过长导致的ANR,这下就可以想办法解决了。