美文网首页
关于Android如何对应用进行Java Crash监控

关于Android如何对应用进行Java Crash监控

作者: 果汁味Studio | 来源:发表于2021-04-26 15:17 被阅读0次
    问题

    android开发或者运行过程中难免会出现Crash,如何持久化崩溃日志便于重新定位

    知识点补充

    Java中的Thread定义了一个接口UncaughtExceptionHandler用于处理未捕获的异常导致线程的终止(值得注意:已经被捕获的异常是捕获不到的)。

    • 当应用crash的时候,就会执行UncaughtExceptionHandler.uncaughtException方法 ,该方法可以获取到异常的信息。
    • 通过Thread.setDefaultUncaughtExceptionHandler 方法可以设置线程的默认异常处理器。
    • 通过Thread.getDefaultUncaughtExceptionHandler();方法可以拿到系统默认的异常处理对象(Android默认的是RuntimeInit.java内部类KillApplicationHandler的实例对象)。
       private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
            private final LoggingHandler mLoggingHandler;
    
            public KillApplicationHandler(LoggingHandler loggingHandler) {
                this.mLoggingHandler = Objects.requireNonNull(loggingHandler);
            }
    
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                try {
                    ensureLogging(t, e);
                    if (mCrashing) return;
                    mCrashing = true;
                    if (ActivityThread.currentActivityThread() != null) {
                        ActivityThread.currentActivityThread().stopProfiling();
                    }
                    ActivityManager.getService().handleApplicationCrash(
                            mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
                } catch (Throwable t2) {
                    if (t2 instanceof DeadObjectException) {
                    } else {
                        try {
                            Clog_e(TAG, "Error reporting crash", t2);
                        } catch (Throwable t3) {
                        }
                    }
                } finally {
                    Process.killProcess(Process.myPid());
                    System.exit(10);
                }
            }
    
    
    解决方案

    Application中调用init()方法即可
    具体实现步骤

    • 获得系统默认的异常处理对象
    • 替换当前系统默认的异常处理对象,为自行实现的异常处理对象
    • 在执行完后,再调用原系统默认的异常处理对象,执行原有操作
    public final class CrashHandler implements Thread.UncaughtExceptionHandler {
    
        private static final CrashHandler mCrashHandler = new CrashHandler();
        private static Thread.UncaughtExceptionHandler mDefaultExceptionHandler;
        private static Context mContext;
        private static final String FILE_NAME_SUFFIX = ".txt";
    
        private CrashHandler() {
        }
    
        public static void init(@NonNull Context context) {
            //获得默认的系统异常的异常处理对象
            mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
            Thread.setDefaultUncaughtExceptionHandler(mCrashHandler);
            mContext = context.getApplicationContext();
        }
    
    
        /**
         * 当程序中有未被捕获的异常,
         * 系统将会调用这个方法
         *
         * @param t 出现未捕获异常的线程
         * @param e 得到异常信息
         */
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            try {//自行处理:保存本地
                File file = dealException(t, e);
            } catch (Exception e1) {
                e1.printStackTrace();
            } finally { //交给系统默认程序处理
                if (null != mDefaultExceptionHandler) {
                    mDefaultExceptionHandler.uncaughtException(t, e);
                }
            }
        }
    
        /**
         * 导出异常信息到本地
         *
         * @param e
         */
        private File dealException(Thread t, Throwable e) throws Exception {
            String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            File f = new File(mContext.getCacheDir().getAbsoluteFile(), "crash_info");
            if (!f.exists()) {
                f.mkdirs();
            }
            File crashFile = new File(f, time + FILE_NAME_SUFFIX);
            PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(crashFile)));
            pw.println(time);
            pw.println("Thread: " + t.getName());
            pw.println(getPhoneInfo());
            e.printStackTrace(pw); //写入crash堆栈
            pw.flush();
            pw.close();
            return crashFile;
        }
    
        /**
         * 用户信息
         *
         * @return
         */
        private String getPhoneInfo() {
            return "";//todo 自定义需要拼接的用户信息
        }
    }
    

    相关文章

      网友评论

          本文标题:关于Android如何对应用进行Java Crash监控

          本文链接:https://www.haomeiwen.com/subject/eebjrltx.html