Android_MVP之错误异常信息收集处理 CrashHandler

程序出错开发者应该尽量避免。可设备种类数不胜数,如果出现了错误我们就应该正确收集出现错误异常的相关信息,
下面是本人在开发时写的一种收集方法。
先在Compontent包下创建CrashHandler.java并实现Thread.UncaughtExceptionHandler。

Thread.UncaughtExceptionHandler:线程未捕获异常处理器,用来处理未捕获异常。如果程序出现了未捕获异常,默认会弹出系统中强制关闭对话框。我们需要实现此接口,并注册为程序中默认未捕获异常处理。这样当未捕获异常发生时,就可以做一些个性化的异常处理操作。

CrashHandler.java 代码如下(详情看注释):

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;

import com.example.chen.news2.app.App;
import com.example.chen.news2.util.LogUtil;
import com.example.chen.news2.util.ToastUtil;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Created by chen on 2017/7/21.
 */

/*
* 全局处理异常
* */
public class CrashHandler implements Thread.UncaughtExceptionHandler{

    public static Thread.UncaughtExceptionHandler defaultHandler = null;

    private Context context = null;

    public final  String TAG = CrashHandler.class.getSimpleName();

    public CrashHandler(Context context){
        this.context = context;
    }

    /*
    * 初始化
    * 设置该CrashHander为程序的默认处理器
    * */

    public static void init(CrashHandler crashHandler){
        defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(crashHandler);
    }

    /*
    * 未处理异常
    * */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        System.out.println(ex.toString());
        LogUtil.e(TAG,  ex.toString());
        LogUtil.e(TAG, collectCrashDeviceInfo());
        LogUtil.e(TAG,  getCrashInfo(ex));
        //调用系统错误机制
        defaultHandler.uncaughtException(thread,ex);
        ToastUtil.shortShow("抱歉,程序发生异常即将退出");
        App.getInstance().exitApp();


    }

    /*
    * 得到程序崩溃的详细信息
    * */
    private String getCrashInfo(Throwable ex) {
        Writer result = new StringWriter();
        PrintWriter printWriter = new PrintWriter(result);
        ex.setStackTrace(ex.getStackTrace());
        ex.printStackTrace(printWriter);
        return result.toString();
    }

    /*
    * 收集程序崩溃的设备信息*/
    private String collectCrashDeviceInfo() {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(),PackageManager.GET_ACTIVITIES);
            String VersionName = packageInfo.versionName;
            String model = Build.MODEL;
            String androidVersion = Build.VERSION.RELEASE;
            String manufacturer = Build.MANUFACTURER;
            return VersionName + " " + model+ " " + androidVersion + " " + manufacturer;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

因为是MVP的结构我们还要写两个工具类,在util包下创建ToastUtil.java和LogUtil.java两个文件。前面是定义一个通知,告诉用户程序出了问题;后面是获取日志,方便反馈和开发者获得具体的错误情况。

ToastUtil.java 代码如下:

package com.example.chen.news2.util;

import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.chen.news2.R;
import com.example.chen.news2.app.App;

/**
 * Created by chen on 2017/7/21.
 */

public class ToastUtil {

    static ToastUtil td;

    public static void show(int resId) {
        show(App.getInstance().getString(resId));
    }

    public static void show(String msg) {
        if (td == null) {
            td = new ToastUtil(App.getInstance());
        }
        td.setText(msg);
        td.create().show();
    }

    public static void shortShow(String msg) {
        if (td == null) {
            td = new ToastUtil(App.getInstance());
        }
        td.setText(msg);
        td.createShort().show();
    }


    Context context;
    Toast toast;
    String msg;

    public ToastUtil(Context context) {
        this.context = context;
    }

    public Toast create() {
        View contentView = View.inflate(context, R.layout.dialog_toast, null);
        TextView tvMsg = (TextView) contentView.findViewById(R.id.tv_toast_msg);
        toast = new Toast(context);
        toast.setView(contentView);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.setDuration(Toast.LENGTH_LONG);
        tvMsg.setText(msg);
        return toast;
    }

    public Toast createShort() {
        View contentView = View.inflate(context, R.layout.dialog_toast, null);
        TextView tvMsg = (TextView) contentView.findViewById(R.id.tv_toast_msg);
        toast = new Toast(context);
        toast.setView(contentView);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.setDuration(Toast.LENGTH_SHORT);
        tvMsg.setText(msg);
        return toast;
    }

    public void show() {
        if (toast != null) {
            toast.show();
        }
    }

    public void setText(String text) {
        msg = text;
    }
}

LogUtil.java 代码如下:

package com.example.chen.news2.util;

import com.orhanobut.logger.BuildConfig;
import com.orhanobut.logger.Logger;

/**
 * Created by chen on 2017/7/21.
 */

public class LogUtil {

    public static boolean isDebug = BuildConfig.DEBUG;
    private static final String TAG = "com.example.chen.news2";

    public static void e(String tag, Object o) {
        if(isDebug) {
            Logger.e(tag, o);
        }
    }

    public static void e(Object o) {
        LogUtil.e(TAG,o);
    }

    public static void w(String tag, Object o) {
        if(isDebug) {
            Logger.w(tag, o);
        }
    }

    public static void w(Object o) {
        LogUtil.w(TAG,o);
    }

    public static void d(String msg) {
        if(isDebug) {
            Logger.d(msg);
        }
    }

    public static void i(String msg) {
        if(isDebug) {
            Logger.i(msg);
        }
    }
}

最后还要在App包下App.java中初始化:

 //初始化日志
        Logger.init(getPackageName()).hideThreadInfo();
  //初始化错误收集
        CrashHandler.init(new CrashHandler(getApplicationContext()));

并且退出程序:

 public void exitApp() {
        if (allActivities != null) {
            synchronized (allActivities) {
                for (Activity act : allActivities) {
                    act.finish();
                }
            }
        }
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(0);
    }

这是我的项目目录:

项目目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值