package com.devtf_l.app.crash; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.Looper; import com.devtf_l.app.BuildConfig; import com.devtf_l.app.activity.ExceptionAlertActivity; /** * @desc 全局异常捕获器 * @author ljh * lijunhuayc@sina.com 2015-4-26 */ public class DevtfUncaughtExceptionHandler implements UncaughtExceptionHandler { private static DevtfUncaughtExceptionHandler crashHandler;// 程序只需要一个全局异常处理 private Context mContext; private UncaughtExceptionHandler defaultExceptionHandler; private Map<String, String> infos = new HashMap<String, String>();// 用来存储设备信息和异常信息 StringBuffer strBuffer = new StringBuffer();// 异常信息 public static DevtfUncaughtExceptionHandler getInstance() { if (null == crashHandler) { synchronized (DevtfUncaughtExceptionHandler.class) { if (null == crashHandler) { crashHandler = new DevtfUncaughtExceptionHandler(); } } } return crashHandler; } /** * @Description: (设置默认异常处理) * @author (ljh) @date 2015-1-30 上午10:28:34 * @return void */ public void init(Context appContext) { mContext = appContext; defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread thread, Throwable ex) { if(BuildConfig.DEBUG) ex.printStackTrace(); // 未处理则让系统默认处理 if (!handleException(ex) && null != defaultExceptionHandler) { defaultExceptionHandler.uncaughtException(thread, ex); } else { Intent intent = new Intent(mContext, ExceptionAlertActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("causeInfo", strBuffer.toString()); mContext.startActivity(intent); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0);// 非0表示非正常退出 } } /** * @Description: (自定义异常处理) * @author (ljh) @date 2015-1-30 下午3:53:38 * @param ex * @return boolean false表示未处理异常 */ private boolean handleException(Throwable ex) { if (null == ex) return false; // mContext.getContentResolver().delete(ProviderConstants.RequestColumns.PROVIDER_Uri_REQUEST, "", null); // mContext.getContentResolver().delete(ProviderConstants.ResultColumns.PROVIDER_Uri_RESULT, "", null); // collectDeviceInfo(); // String filePath = saveCrashInfo2File(ex); // TODO ...文件上传在哪里 return true; } private void collectDeviceInfo() { try { PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); if (null != pi) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; infos.put("versionName", versionName); infos.put("versionCode", versionCode); } } catch (NameNotFoundException e) { // LogUtils.e("an error occured when collect package info", e); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString()); } catch (Exception e) { // LogUtils.e("an error occured when collect crash info", e); } } } private String saveCrashInfo2File(Throwable ex) { for (Entry<String, String> entry : infos.entrySet()) { strBuffer.append(entry.getKey() + " = " + entry.getValue() + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (null != cause) { cause.printStackTrace(printWriter); cause = cause.getCause(); } // printWriter.close(); // strBuffer.append(writer.toString()); // SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss_sss", Locale.CHINA); // String ecptPath = Constants.FILE_LOG_PATH + "/crash_" + sdf.format(new Date()) + ".txt"; // File ecptFile = new File(ecptPath); // if (!ecptFile.exists()) { // ecptFile.getParentFile().mkdirs(); // } // try { // DataOutputStream dos = new DataOutputStream(new FileOutputStream(ecptFile)); // dos.writeChars(strBuffer.toString()); // dos.close(); // } catch (Exception e) { // LogUtils.e("an error occured while writing file...", e); // } // return ecptPath; return ""; } }