安卓全局异常捕获,异常崩溃处理
开发安卓的小伙伴都遇到过APP突然崩溃,无响应的情况.如果发生在自己手中,那么还可以通过IDE查看错误日志,但是实际都是发生在用户手中,那么这个时候产生崩溃,无响应ANR异常就很麻烦.无从下手.因此,需要全局异常捕获.也就是对未知异常,程序员没有处理的异常进行处理,记录等便于分析查找原因.
首先,新建一个类 MyCatchException.Java
package com.linfeng.activity; import android.content.Context; import android.os.Looper; import android.util.Log; import android.widget.Toast; import com.linfeng.util.Util; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; /** * Created by Linfeng on 2019/05/14. */ //全部错误捕捉器 public class MyCatchException implements Thread.UncaughtExceptionHandler { //本类实例 private static MyCatchException mInstance; //系统默认的uncatchException private Thread.UncaughtExceptionHandler mDefaultException; private Context mContext; //保证只有一个实例 public MyCatchException() { } //单例模式 public static MyCatchException getInstance() { if (mInstance == null) { mInstance = new MyCatchException(); } return mInstance; } //获取系统默认的异常处理器,并且设置本类为系统默认处理器 public void init(Context ctx) { this.mContext = ctx; mDefaultException = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } //自定义错误处理器 private boolean handlerException(Throwable ex) { if (ex == null) { //如果已经处理过这个Exception,则让系统处理器进行后续关闭处理 return false; } //获取错误原因 Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause!=null){ cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String result = writer.toString(); final String msg= result ; new Thread() { public void run() { // Toast 显示需要出现在一个线程的消息队列中 Looper.prepare(); Toast.makeText(mContext, "程序出错:" + msg.toString(), Toast.LENGTH_LONG).show(); //将异常记录到本地的数据库或者文件中.或者直接提交到后台服务器 Util.writeLog("全局异常",msg); Looper.loop(); } ; }.start(); return true; } @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handlerException(ex) && mDefaultException != null) { // 如果用户没有处理则让系统默认的异常处理器来处理 mDefaultException.uncaughtException(thread, ex); } else { //否则自己进行处理 try { //Sleep 来让线程停止一会是为了显示Toast信息给用户,然后Kill程序 Thread.sleep(3000); } catch (InterruptedException e) { Util.writeLog("全局异常",e.getMessage()); Log.d("2635", "uncaughtException: "+e.getMessage()); }catch (Exception e){ Util.writeLog("全局异常",e.getMessage()); Log.d("2635", "Exception: "+e.getMessage()); } //如果不关闭程序,会导致程序无法启动,需要完全结束进程才能重新启动 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); } } }
然后在APP的application中注册,但是由于一般application都可能用了,或者不方便修改.一般采用在APP的第一个Activity中进行注册,那么我这里在我第一个Activity,也就是SplashActivity页面的onCreate方法中添加这两句代码
MyCatchException mException=MyCatchException.getInstance(); mException.init(getApplicationContext()); //注册
这样就完成了,当我们app有没有处理的异常时,就会自动帮我们捕获异常.可以做一个测试.
比如,在MainActivity中随便抛出一个异常,比如数组越界,空指针异常等去测试是否能捕获这个异常.