博客爲 有時個哥 原創,如需轉載請標明出處:http://blog.csdn.net/ls703/article/details/43022243
在android中總會遇到應用崩潰現在,我們要修改就需要得帶異常日誌,所以我們要對崩潰時做一些友好處理,或得到日誌上傳服務器等操作。
這是就需要用到UncaughtExceptionHandler這個接口,這個接口是用來操作捕獲應用中爲捕獲到的異常操作。
我們可以繼承這個接口,來對全局崩潰異常做處理或信息收集。
現在寫一個繼承UncaughtExceptionHandler的類如下:
package ls.utils.crash;
import java.lang.Thread.UncaughtExceptionHandler;
import ls.utils.ActivityUtils;
import ls.utils.LogUtils;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class WholeCrashHandler implements UncaughtExceptionHandler {
private static final String TAG = "TAG";
/***************************** 單例模式 ***************************************/
private static WholeCrashHandler crashHandler = new WholeCrashHandler();
private WholeCrashHandler() {
}
public static WholeCrashHandler getInstance() {
return crashHandler;
}
/***************************************************************************/
private static final boolean ISOPEN = true; // 是否打開日誌寫入和發送
private Thread.UncaughtExceptionHandler mDefaultHandler;
private Context context;
public void init(Context context) {
LogUtils.i(TAG, "zhuce=====");
this.context = 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 {
Activity currentActivity = ActivityUtils.Instance().getCurrentActivity();
LogUtils.i(TAG, "current===>>>>."+currentActivity);
ActivityUtils.Instance().finishAll();
Intent intent = new Intent();
intent.setClass(context, CrashHintActivity1.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
LogUtils.i(TAG, "zhuce==111===");
context.startActivity(intent);
LogUtils.i(TAG, "zhuce==2222===");
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/**
* 異常處理
*
* @param ex
* 異常信息
* @return boolean true 已處理,false 未處理
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
if (!ISOPEN) {
return false;
}
//收集設備信息
// 寫入本地文件
LogUtils.write(ex);
//可以在這直接操作發送log日誌
return true;
}
}
uncaughtException()這個方法會被回調,當出現崩潰時,handleException()方法是判斷是否自己經行處理,如果沒有就調用系統默認的對話框,
handleException()方法裏是我們自己做的處理,在這裏面可以把異常信息寫入文件,手機設備信息,或把異常信息傳到服務後臺,這就看你到是要求怎麼處理的了。
這裏值實現了寫入本地文件的操作,關於LogUtils.weite();這個方法,在上一篇博客中(Log日誌工具類)已經給出了,http://blog.csdn.net/ls703/article/details/42973553
可去複製的。
然後就是uncaughtException()方法中的else部分的處理了,這部分是表示,已經對崩潰經行處理了之後的後續操作,在這裏可以直接殺死應用,安全退出,也可以重起應用,也就是跳轉到app的一個activity。值得注意的事,由於此時本應用處於出錯狀態,正常的跳轉是沒法完成的。得開闢新的棧來存放新開起的activity,所以在跳轉activity是要加上intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);在此時看來,此處就相當於重新啓動了一個app。這裏的操作是走application的。如果你自己調試看一下,會看到,當前代碼執行完,再重新走application,然後在啓動跳轉到的activity的。
下一步就是把我們這個類放到應用中,這個類放到application中,初始化一次就ok了。
public class AppContext extends Application {
@Override
public void onCreate() {
super.onCreate();
WholeCrashHandler.getInstance().init(getApplicationContext());
}
}
當然少不了在清單文件中替換自己的application了,
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="com.application.AppContext"
>
在上面的name屬性,找到自己寫的繼承了application的類就可以了。