您的位置:首页 > 移动开发 > Android开发

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

2017-07-21 15:18 453 查看
程序出错开发者应该尽量避免。可设备种类数不胜数,如果出现了错误我们就应该正确收集出现错误异常的相关信息,

下面是本人在开发时写的一种收集方法。

先在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.getDefaultUncaugh
4000
tExceptionHandler();
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);
}


这是我的项目目录:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐