• 安卓全局异常捕获,异常崩溃处理


    开发安卓的小伙伴都遇到过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中随便抛出一个异常,比如数组越界,空指针异常等去测试是否能捕获这个异常.

  • 相关阅读:
    P1217 [USACO1.5]回文质数 Prime Palindromes
    C++ 队列(queue)堆栈(stack)实现基础
    深入理解指针—>指针函数与函数指针的区别
    C语言结构体及typedef关键字定义结构体别名和函数指针的应用
    实现常用的配置文件/初始化文件读取的一个C程序
    C语言sscanf和sprintf输入输出使用及Strlen、Memset解释
    C语言一些基础知识
    Google的开源C++单元测试框架Google Test
    网站(Web)压测工具Webbench源码分析
    web压测工具http_load原理分析
  • 原文地址:https://www.cnblogs.com/linfenghp/p/10867899.html
Copyright © 2020-2023  润新知