public class CrashHandler implements UncaughtExceptionHandler {
/** 系統預設的異常處理類 */
private Thread.UncaughtExceptionHandler mDefaultHandler;
private static CrashHandler INSTANCE = new CrashHandler();
public static CrashHandler getInstance() {
return INSTANCE;
}
public void init(Context context) {
mcontext = context;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 擷取預設的異常處理類
Thread.setDefaultUncaughtExceptionHandler(this);// 設定目前處理類為預設的異常處理類
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);// 如果未處理異常,那麼系統預設的異常處理類處理
} else {
try {
Thread.sleep();
} catch (Exception e) {
// TODO: handle exception
}
// 退出程式
// android.os.Process.killProcess(android.os.Process.myPid());
// System.exit(1);
// mcontext.startActivity(new Intent(mcontext, LogoActivity.class));
// Intent intent = new Intent(mcontext.getApplicationContext(),
// LogoActivity.class);
// intent.putExtra("Error", true);
// intent.putExtra("FilePath", file);
//
// PendingIntent pendingIntent = PendingIntent.getActivity(
// mcontext.getApplicationContext(), 0, intent,
// Intent.FLAG_ACTIVITY_NEW_TASK);
// AlarmManager mgr = (AlarmManager) mcontext
// .getSystemService(Context.ALARM_SERVICE);
// mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 400,
// pendingIntent); // 1秒鐘後重新開機應用
android.os.Process.killProcess(android.os.Process.myPid());
System.exit();
}
}
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mcontext, "程式出錯了,即将退出!我們會盡快修複!",
Toast.LENGTH_LONG).show();
Looper.loop();
};
}.start();
file = saveCrashInfo2File(ex);
saveCrashInfoIntoSd(ex);
return true;// 測試階段全部抛出
// return false;
}
}
将錯誤資訊儲存到SD卡:
/**
* 儲存錯誤資訊到SD卡檔案中
*
* @param ex
* @return 傳回檔案名稱,便于将檔案傳送到伺服器
*/
private void saveCrashInfoIntoSd(Throwable ex) {
if(isSdCardExist()) {
String errPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/AppError/";
File dir = new File(errPath);
if (!dir.exists()) {
dir.mkdirs();
}
String time = formatter.format(new Date());
String fileName = "crash-" + time + ".txt";
try {
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();
final String result = writer.toString();
File file = new File(errPath + "//" + fileName);
if(!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(result.toString().getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 判斷SDCard是否存在 [當沒有外挂SD卡時,内置ROM也被識别為存在sd卡]
*
* @return
*/
public static boolean isSdCardExist() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
将錯誤資訊儲存到APP系統檔案中:
/**
* 儲存錯誤資訊到檔案中
*
* @param ex
* @return 傳回檔案名稱,便于将檔案傳送到伺服器
*/
private String saveCrashInfo2File(Throwable ex) {
String path = "/sdcard/ConfigZlnurse/";
File file1 = mcontext.getFilesDir();
// String path = file1.getPath() + "/ConfigZlnurse/";
// StringBuffer sb = new StringBuffer();
// for (Map.Entry<String, String> entry : infos.entrySet()) {
// String key = entry.getKey();
// String value = entry.getValue();
// sb.append(key + "=" + value + "\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();
final String result = writer.toString();
try {
long timestamp = System.currentTimeMillis();
String time = formatter.format(new Date());
String fileName = "crash-" + time + "-" + timestamp
+ CRASH_REPORTER_EXTENSION;
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path + fileName);
file = path + fileName;
fos.write(result.toString().getBytes());
fos.close();
}
return path + fileName;
} catch (Exception e) {
Log.e(TAG, "an error occured while writing file...", e);
}
return null;
}
use:
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());