捕获异常信息本地查看或者上传服务器

app运行在手机上,如果没有连接开发工具,那么报错的时候是看不到异常信息的,下面的这种方法,是把日志保存在手机文件里面,可以通过文件管理器查看,方便了开发者找异常

同时,这种方式也是多数开发者的选择,打印在本地,等下次开启应用并且有网的情况下,再把文件上传给服务器,这样就可以在服务器端很便捷的捕获不同用户的异常了,很方便维护


先写一个如下的类:

public class CrashHandler implements Thread.UncaughtExceptionHandler {
    public static final String TAG = "CrashHandler";
    private Context mContext;
    private static CrashHandler crashHandler;
    private Thread.UncaughtExceptionHandler defaultHandler;
    private DateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    private Map<String, String> infos = new HashMap<>();

    private CrashHandler() {
    }

    public static CrashHandler newsIntance() {

        if (crashHandler == null) {
            synchronized (CrashHandler.class) {
                if (crashHandler == null) {
                    crashHandler = new CrashHandler();
                }
            }
        }

        return crashHandler;
    }

    public void init(Context context) {
        mContext = context;
        defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {

        if (!handleException(ex) && defaultHandler != null) {
            defaultHandler.uncaughtException(thread, ex);
        }else {
            defaultHandler.uncaughtException(thread, ex);
        }
    }

    private boolean handleException(Throwable ex) {

        if (ex == null) {
            return false;
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(mContext, "很抱歉,程序出现异常", Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        }).start();

        collectPackageeInfo();

        saveCrashInfo2File(ex);
        return true;
    }

    private void collectPackageeInfo() {
        try {
            PackageManager pm = mContext.getPackageManager();
            PackageInfo packageInfo = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
            if (packageInfo != null) {
                infos.put("versionName", packageInfo.versionName == null ? "null" : packageInfo.versionName);
                infos.put("versionCode", packageInfo.versionCode + "");
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

    }

    private void saveCrashInfo2File(Throwable ex) {

        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : infos.entrySet()) {
            sb.append(entry.getKey() + " = " + entry.getValue() + "\n");
        }

        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();
        sb.append(result);
        try {
            String time = format.format(new Date());
            String appName = mContext.getResources().getString(R.string.app_name);
            String fileName = "crash-" + time + "-" + appName + ".log";
            String path = Environment.getExternalStorageDirectory() + "/crash/";
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            FileOutputStream fos = new FileOutputStream(path + fileName);
            fos.write(sb.toString().getBytes());
            fos.close();
        } catch (Exception e) {
            Log.e(TAG, "an error occured while writing file...", e);
        }

    }

}


然后再Application子类里面: CrashHandler.newsIntance().init(this);

public class QuestionApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        CrashHandler.newsIntance().init(this);
    }
}

最后在Manifest.xml里面配置自己的Application子类

<application
    xxxx
    android:name=".QuestionApplication"
    xxxx>


之后这个应用是可以在sd卡里面的crash文件夹里面找到打印的异常日志信息。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值