ANR以及解决方法以及捕获未捕获的异常
ANR
如果我们的应用在一段时间内没有响应,系统就会报错:Application Not Responding(ANR)。
造成ANR的场景如下:
1 . Activity中5s未响应;
2 . Broadcast中10s未响应;
3 . Service中20s未响应;
ANR一般有三种类型:
1 . KeyDispatchTimeout(5s):按键或触摸事件在5s内无响应;
2 . BroadcastTimeout(10s):BroadcastReceiver在10s内未处理完;
3 . ServiceTimeout(20s):Service在20s内未处理完;
超时的原因一般有两种:
1 . 当前的事件没有机会得到处理(UI线程正在处理前一个事件,没有及时完成或者looper被某种原因阻塞了);
2 . 当前的事件正在处理,但是没有及时完成;
UI线程应该尽量只做跟UI相关的工作,耗时的工作放入到单独的线程中处理,尽量使用Handler来处理UI 线程和其他线程之间的交互。
查找ANR的方式:
1 . 导出/data/data/anr/traces.txt,找出函数和调用过程,分析代码;
捕获未捕获的异常
捕获未捕获的异常有两种方式,一种是使用代码,一种是使用第三方工具;
使用UncaughtExceptionHandler
使用步骤如下:
1 . 自定义一个Application,并在该Application中实现Thread.UncaughtExceptionHandler接口。实现Thread.UncaughtExceptionHandler接口,自然就会实现uncaughtException()方法;
public class MyApplication extends Application implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
}
}
2 . 在该Application的onCreate()方法和uncaughtException()方法中来实现业务逻辑;
@Override
public void onCreate() {
super.onCreate();
//给Thread设置默认异常处理的handler,这一行代码是必须写的;
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
//开辟新线程进行异常的收集,然后等待三秒后杀掉应用;
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
//收集异常,现在这里我们没有做具体的业务逻辑,但是实际开发中这里做相应的业务逻辑处理;
Log.e(TAG, "currentThread:" + Thread.currentThread());
Looper.loop();
}
}).start();
//延迟三秒杀掉应用;
SystemClock.sleep(3000);
Process.killProcess(Process.myPid());
}
3 . 在AndroidManifest.xml文件中配置该Application;
<application
android:name=".app.MyApplication"
</application>
使用Bug收集工具Crashlytics
该工具还未在项目使用,以后再补充这部分;