在做項目時,經常會把錯誤利用異常拋出去,這樣在開發時就可以通過手機拋出的異常排查錯誤。但是當程式開發完畢,版本穩定,需要上線時,為了避免拋出異常影響使用者感受,可以用UncaughtExceptionHandler捕獲全域異常,對異常做出處理。比如我們可以擷取到拋出異常的時間、手機的硬體資訊、錯誤的堆棧資訊,然後將擷取到的所有的資訊發送到伺服器中,也可以發送到指定的郵件中,以便及時修改bug。
樣本:
自訂異常類實現UncaughtExceptionHandler介面,當某個頁面出現異常就會調用uncaughtException這個方法,我們可以在這個方法中擷取異常資訊、時間等,然後將擷取到的資訊發送到我們指定的伺服器
複製代碼 代碼如下:
/**
* 自訂的 異常處理類 , 實現了 UncaughtExceptionHandler介面
* @author Administrator
*
*/
public class MyCrashHandler implements UncaughtExceptionHandler {
// 需求是 整個應用程式 只有一個 MyCrash-Handler
private static MyCrashHandler myCrashHandler ;
private Context context;
private DoubanService service;
private SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
//1.私人化構造方法
private MyCrashHandler(){
}
public static synchronized MyCrashHandler getInstance(){
if(myCrashHandler!=null){
return myCrashHandler;
}else {
myCrashHandler = new MyCrashHandler();
return myCrashHandler;
}
}
public void init(Context context,DoubanService service){
this.context = context;
this.service = service;
}
public void uncaughtException(Thread arg0, Throwable arg1) {
System.out.println("程式掛掉了 ");
// 1.擷取當前程式的版本號碼. 版本的id
String versioninfo = getVersionInfo();
// 2.擷取手機的硬體資訊.
String mobileInfo = getMobileInfo();
// 3.把錯誤的堆棧資訊 擷取出來
String errorinfo = getErrorInfo(arg1);
// 4.把所有的資訊 還有資訊對應的時間 提交到伺服器
try {
service.createNote(new PlainTextConstruct(dataFormat.format(new Date())),
new PlainTextConstruct(versioninfo+mobileInfo+errorinfo), "public", "yes");
} catch (Exception e) {
e.printStackTrace();
}
//幹掉當前的程式
android.os.Process.killProcess(android.os.Process.myPid());
}
/**
* 擷取錯誤的資訊
* @param arg1
* @return
*/
private String getErrorInfo(Throwable arg1) {
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
arg1.printStackTrace(pw);
pw.close();
String error= writer.toString();
return error;
}
/**
* 擷取手機的硬體資訊
* @return
*/
private String getMobileInfo() {
StringBuffer sb = new StringBuffer();
//通過反射擷取系統的硬體資訊
try {
Field[] fields = Build.class.getDeclaredFields();
for(Field field: fields){
//暴力反射 ,擷取私人的資訊
field.setAccessible(true);
String name = field.getName();
String value = field.get(null).toString();
sb.append(name+"="+value);
sb.append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 擷取手機的版本資訊
* @return
*/
private String getVersionInfo(){
try {
PackageManager pm = context.getPackageManager();
PackageInfo info =pm.getPackageInfo(context.getPackageName(), 0);
return info.versionName;
} catch (Exception e) {
e.printStackTrace();
return "版本號碼未知";
}
}
}
建立一個Application執行個體將MyCrashHandler註冊到整個應用程式上,建立出服務並進行傳遞:
複製代碼 代碼如下:
/**
* 整個(app)程式初始化之前被調用
* @author Administrator
*
*/
public class DoubanApplication extends Application {
public NoteEntry entry;
@Override
public void onCreate() {
super.onCreate();
String apiKey = "0fab7f9aa21f39cd2f027ecfe65dad67";
String secret = "87fc1c5e99bfa5b3";
// 擷取到service
DoubanService myService = new DoubanService("我的小豆豆", apiKey,
secret);
myService.setAccessToken("1fa4e5be0f808a0b5eeeb13a2e819e21", "56a622c1138dbfce");
MyCrashHandler handler = MyCrashHandler.getInstance();
handler.init(getApplicationContext(),myService);
Thread.setDefaultUncaughtExceptionHandler(handler);
}
}