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

  该工具还未在项目使用,以后再补充这部分;