Android性能优化之UncaughtExceptionHandler定制自己的错误日志系统

前言:

每当我们app测试的时候,测试人员总是对我们说这里崩溃了,那里挂掉了!我们只能默默接受,然后尝试着重现bug,更可悲的是有时候bug很难复现,为了解决这种现状所以我们要尝试这建立一个自己的bug日志系统。

实现原理:

Java为我们提供了一个机制,用来捕获并处理在一个线程对象中抛出的未检测异常,以避免程序终止。我们可以通过UncaughtExceptionHandler来实现这种机制。

 

具体实现:

public class CrashManager implements UncaughtExceptionHandler {
    public static final String TAG = "CrashHandler";
    // CrashHandler实例
    private static CrashManager instance;
    // 程序的Context对象
    private Application application;
    // 系统默认的UncaughtException处理类
    private UncaughtExceptionHandler mDefaultHandler;

    /**
     * 保证只有一个CrashHandler实例
     */
    private CrashManager(Context context) {
        application = (Application) context.getApplicationContext();
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 获取CrashHandler实例 ,单例模式
     */
    public static CrashManager getInstance(Context context) {
        CrashManager inst = instance;
        if (inst == null) {
            synchronized (CrashManager.class) {
                inst = instance;
                if (inst == null) {
                    inst = new CrashManager(context.getApplicationContext());
                    instance = inst;
                }
            }
        }
        return inst;
    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        TaskManager.getInstance(application).saveErrorLog(ex);
        mDefaultHandler.uncaughtException(thread, ex);
    }

}

日志写入sdcard代码:

public class SaveErrorTask<T> extends Task<Object, Object, Void> {
    private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.CHINA);
    private Context context;
    private Throwable ex;

    public SaveErrorTask(Context context, Throwable ex) {
        setPriority(TaskPriority.UI_LOW);
        this.context = context;
        this.ex = ex;
    }

    @Override
    protected Void doInBackground(Object... arg0) {
        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();
        String time = formatter.format(new Date());
        String fileName = time + ".txt";
        StringBuilder stringBuffer = new StringBuilder();
        DeviceInfo deviceInfo = Utils.getDeviceInfo(context);
        stringBuffer.append("\nsdkVersion:" + deviceInfo.sdkVersion);
        stringBuffer.append("\nmanufacturer:" + deviceInfo.manufacturer);
        stringBuffer.append("\nmodel:" + deviceInfo.model);
        stringBuffer.append("\nversion" + ConfigManager.getVersionName(context));
        stringBuffer.append("\nerrorStr:" + result);
        stringBuffer.append("\ntime:" + time);
        String filePath = CacheFileUtils.getLogPath(fileName);
        CacheFileUtils.saveErrorStr(filePath, stringBuffer.toString());
        return null;
    }
}

初始化:

public class MyApplication extends MultiDexApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        //初始化 错误日子系统
        CrashManager.getInstance(this);
       
    }
}

 

 

展望:我们也可以把日志再下次启动的时候发送至我们自己的日志服务器,监控用户错误信息

posted on 2016-05-07 13:08  总李写代码  阅读(9690)  评论(1编辑  收藏  举报