android崩溃日志收集

孤人 提交于 2020-02-17 04:21:14

收集android的崩溃

主要步骤:

  1. 实现UncaughtExceptionHandler
    我们需要实现UncaughtExceptionHandler接口中的uncaughtException方法。该方法中最常见的操作就是读取崩溃的stacktrace,然后上报服务器数据便于分析。
    实现代码

    public class SimpleUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        private static final String LOGTAG = "SimpleUncaughtExceptionHandler";
    
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
          //读取stacktrace信息
            final Writer result = new StringWriter();
            final PrintWriter printWriter = new PrintWriter(result);
            ex.printStackTrace(printWriter);
            String errorReport = result.toString();
            Log.i(LOGTAG, "uncaughtException errorReport=" + errorReport);
        }
    }
    除此之外,还建议携带以下信息发送到服务器,帮助更快定位和重现问题。
    • 设备唯一ID(基于IMEI或者Android ID等),方便根据用户提供的id,查找崩溃的stacktrace
    • 设备语言与区域 方便重现
    • 应用的版本号
    • 设备的系统版本
    • 设备类型,如平板,手机,TV等
    • 崩溃发生的时间等
  2. 注册默认的异常处理

    public class DroidApplication extends Application {
        private static final String LOGTAG = "DroidApplication";
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i(LOGTAG, "onCreate");
            Thread.setDefaultUncaughtExceptionHandler(new SimpleUncaughtExceptionHandler());
        }
    }

有些崩溃不想让用户感知->屏蔽系统弹窗

一般采取策略是主线程弹窗,其他线程不弹窗策略

  1. 首先判断进程是不是主线程

    //获取当前进程的名称
    public static String getProcessName(Context appContext) {
        String currentProcessName = "";
        int pid = android.os.Process.myPid();
        ActivityManager manager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
                if (processInfo.pid == pid) {
                currentProcessName = processInfo.processName;
                break;
            }
        }
        return currentProcessName;
    }
    
    //判断主进程,对比进程名是否和包名相同
    mAppContext.getPackageName().equals(processName);
    //其他线程
    <service android:name=".DroidService" android:process=":service"></service>
    //其对应的完整进程名为com.droidyue.avoidforceclosedemo:service,我们判断可以使用如下代码
    "com.droidyue.avoidforceclosedemo:service".equals(processName);
  2. 不弹窗处理
    不弹框的需要做的就是不调用Android默认的异常处理,当异常出现时,收集完信息,执行进程kill即可。
    java android.os.Process.killProcess(android.os.Process.myPid());

  3. 主进程保持弹窗处理

    /**
    * 首先需要获得Android默认的异常处理,在设置自定的异常处理之前,将Android默认处理保存起来。如下是在自定义异常处理的构造方法中获取        Android默认处理
    */
    public DroidUncaughtExceptionHandler(Context context) {
        mAppContext = context.getApplicationContext();
        mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
    }
    
    //然后在异常处理方法uncaughtException中调用如下方法
    mDefaultExceptionHandler.uncaughtException(thread, ex);

本示例源码,存放在Github,地址为
AvoidForceCloseDemo







引用:http://droidyue.com/blog/2015/12/06/practise-about-crash-in-android/?utm_source=tuicool&utm_medium=referral

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!