在開發(fā)過程中或者在程序正式上線以后,總是或多或少的出現(xiàn)程序崩潰的情況,大多是程序在測試的時候,沒有完整測試。此時,自定義全局未處理異常捕捉器就顯得非常有用了
實現(xiàn)步驟:
- 自定義全局未處理異常捕捉器,需要實現(xiàn)
UncaughtExceptionHandler接口,并重寫uncaughtException(Thread thread, Throwable ex)方法 - 在
Application或者主頁面Activity或者某個Activity中,調(diào)用方法Thread.setDefaultUncaughtExceptionHandler,設(shè)置自定義的異常捕捉器為默認(rèn)的全局異常捕捉器
實現(xiàn)栗子
在主頁面中設(shè)置異常捕捉器,在第二個界面中發(fā)生異常,提示用戶程序崩潰,將異常原因以文本形式保存到本地,重新啟動程序進(jìn)入主頁面
自定義異常捕捉器:
public class MyExceptionHanlder implements UncaughtExceptionHandler {
private Context mContext = null;
private String className = "";
public MyExceptionHanlder(Context context) {
this.mContext = context;
}
public MyExceptionHanlder(Context context, String className) {
this.mContext = context;
this.className = className;
}
/**
* 當(dāng)自定義的異常捕獲異常處理器被設(shè)置為此APP默認(rèn)的異常處理器,
* 發(fā)生未處理異常時,此方法會被自動調(diào)用
* @param thread 所發(fā)生異常所在的線程
* @param ex 拋出的未處理異常Throwable對象
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (ex != null) {
Log.i("UncaughtException", ex.getMessage());
StringBuilder sb = new StringBuilder();
String temp = ex.getMessage();
if (temp != null) {
sb.append("ex.getMessage():");
sb.append(System.getProperty("line.separator"));
sb.append(temp);
}
sb.append(System.getProperty("line.separator"));
sb.append("thread.getName():" + thread.getName());
sb.append(System.getProperty("line.separator"));
sb.append(" Trace: " + System.getProperty("line.separator"));
StackTraceElement[] elements = ex.getStackTrace();
if (elements != null) {
for (StackTraceElement element : elements) {
temp = element.toString();
if (temp != null) {
sb.append(temp);
}
sb.append(System.getProperty("line.separator"));
}
}
sb.append("Cause: ");
sb.append(System.getProperty("line.separator"));
Throwable theCause = ex.getCause();
if (theCause != null) {
temp = theCause.toString();
if (temp != null) {
sb.append(temp);
}
}
sb.append(System.getProperty("line.separator") + " Cause Stack: " +
System.getProperty("line.separator"));
theCause = ex.getCause();
if (theCause != null) {
elements = theCause.getStackTrace();
if (elements != null) {
for (StackTraceElement element : elements) {
temp = element.toString();
if (temp != null) {
sb.append(temp);
}
sb.append(System.getProperty("line.separator"));
}
}
}
try {
//將異常信息存入本地文件
this.writeCrashLog(sb);
} catch (Exception e) {
e.printStackTrace();
}
//彈出自定義處理異常界面
Intent intent = new Intent(mContext, ExceptionDialog.class);
intent.putExtra("className", className);
mContext.startActivity(intent);
//銷毀頁面,殺死APP進(jìn)程
crash(mContext);
}
}
/**
* 將異常信息存入本地信息
* @param sb StringBuilder對象
* @throws Exception 拋出異常對象
*/
private void writeCrashLog(StringBuilder sb) throws Exception {
//存儲路徑
String path = Environment.getExternalStorageDirectory() + "/crashLog.txt";
Log.d("Main", path);
File logFile = new File(path);
if (!logFile.exists()){
logFile.createNewFile();
}else{
logFile.delete();
logFile.createNewFile();
}
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(logFile));
bufferedWriter.write(sb.toString());
bufferedWriter.close();
Toast.makeText(mContext, "寫入成功", Toast.LENGTH_LONG).show();
}
/**
* 銷毀頁面以及關(guān)閉APP進(jìn)程
* @param context 上下文對象
* @return 是否銷毀頁面以及當(dāng)前進(jìn)程
*/
public static boolean crash(Context context) {
if (context == null) {
return false;
}
//銷毀頁面
if (context instanceof Activity) {
((Activity) context).finish();
}
//殺死APP進(jìn)程
Process.killProcess(Process.myPid());
return true;
}
**源文件下載地址:http://download.csdn.net/detail/xiaoshengfdyh/9704576**