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

Android UncaughtExceptionHandler捕获crash的全局异常

2016-07-04 19:05 453 查看
Android App在crash的时候可以做一些操作,比方说记录异常文件并上传到服务器,或者接入类似腾讯bugly的异常分析平台,一个简单的做法就是前者,实现的代码如下:

package com.duoyin.stock.activity;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.Process;
import android.util.Log;

import com.duoyin.stock.util.HAUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* Created by yeh on 2016/7/4.
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG = CrashHandler.class.getName();
private static final boolean DEBUG = true;

private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/yehTest/log/";// log path
private static final String FILE_NAME = "crash";

private static final String FILE_NAME_SUFFIX = ".trace";

private static CrashHandler sInstance = new CrashHandler();
// 系统默认的异常处理(默认情况下,系统会终止当前的异常程序)
private Thread.UncaughtExceptionHandler mDefaultCrashHandler;

private Context mContext;

private CrashHandler() {
}

public static CrashHandler getInstance() {
return sInstance;
}

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

@Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
HAUtils.showMsg(mContext, "呃呃~~程序crash了~~~");
// 导出当前的错误信息到sdcard
dumpExceptionToSDCard(ex);
uploadExceptionToServer();
} catch (Exception e) {
e.printStackTrace();
}

ex.printStackTrace();

if (mDefaultCrashHandler != null) {
mDefaultCrashHandler.uncaughtException(thread, ex);
} else {
Process.killProcess(Process.myPid());
}
}

/**
* 上传异常到服务器
*/
private void uploadExceptionToServer() {
}

/**
* 导出信息到SDCard
*
* @param ex
*/
private void dumpExceptionToSDCard(Throwable ex) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
if (DEBUG) {
Log.w(TAG, "sdcard unmounted,skip dump exception");
}
}

File dir = new File(PATH);
if (!dir.exists()) {
dir.mkdirs();
}

long current = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
File file = new File(PATH + FILE_NAME + time + FILE_NAME_SUFFIX);

if (!file.exists()) {
file.mkdir();
}

try {
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
pw.println(time);
// 导出手机信息
dumpPhoneInfo(pw);
pw.println();
// 导出异常的调用栈信息
ex.printStackTrace(pw);
} catch (Exception e) {
Log.e(TAG, "dump crash info failed");
}
}

private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException {
//应用的版本名称和版本号
PackageManager pm = mContext.getPackageManager();
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
pw.print("App Version: ");
pw.print(pi.versionName);
pw.print('_');
pw.println(pi.versionCode);

//android版本号
pw.print("OS Version: ");
pw.print(Build.VERSION.RELEASE);
pw.print("_");
pw.println(Build.VERSION.SDK_INT);

//手机制造商
pw.print("Vendor: ");
pw.println(Build.MANUFACTURER);

//手机型号
pw.print("Model: ");
pw.println(Build.MODEL);

//cpu架构
pw.print("CPU ABI: ");
pw.println(Build.CPU_ABI);
}
}

另外因为是全局操作需要在Application中调用如下的操作即可:

CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(this);

参考了任玉刚博客:
http://blog.csdn.net/singwhatiwanna/article/details/17289479
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: