UncaughtException處理類,當程序發生Uncaught異常的時候,有該類來接管程序,并記錄發送錯誤報告.
1.java文件
public class CrashHandler implements Thread.UncaughtExceptionHandler {public static final String TAG =
"CrashHandler";
private static CrashHandler INSTANCE =
new CrashHandler();
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultHandler;
private Map<String, String> infos =
new HashMap<String, String>();
private DateFormat formatter =
new SimpleDateFormat(
"yyyy-MM-dd-HH-mm-ss");
/** 保證只有一個 CrashHandler 實例 */private CrashHandler() {}
/** 獲取 CrashHandler 實例 ,單例模式 */public static CrashHandler
getInstance() {
return INSTANCE;}
/*** 初始化** @param context*/public void init(Context context) {mContext = context;mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(
this);}
/*** 當 UncaughtException 發生時會轉入該函數來處理*/@Overridepublic void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler !=
null) {mDefaultHandler.uncaughtException(thread, ex);}
else {
try {Thread.sleep(
2000);}
catch (InterruptedException e) {Log.e(TAG,
"error : ", e);}App.application.RemoveActivity();android.os.Process.killProcess(android.os.Process.myPid());}}
/*** 自定義錯誤處理,收集錯誤信息,發送錯誤報告等操作均在此完成** @param ex* @return true:如果處理了該異常信息;否則返回 false*/private boolean handleException(Throwable ex) {
if (ex ==
null) {
return false;}
new Thread() {
@Overridepublic void run() {Looper.prepare();Toast.makeText(mContext,
"很抱歉,程序出現異常,即將退出。", Toast.LENGTH_LONG).show();Looper.loop();}}.start();collectDeviceInfo(mContext);saveCrashInfo2File(ex);
return true;}
/*** 收集設備參數信息* @param ctx*/public void collectDeviceInfo(Context ctx) {
try {PackageManager pm = ctx.getPackageManager();PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi !=
null) {String versionName = pi.versionName ==
null ?
"null" : pi.versionName;String versionCode = pi.versionCode +
"";infos.put(
"versionName", versionName);infos.put(
"versionCode", versionCode);}}
catch (PackageManager.NameNotFoundException e) {Log.e(TAG,
"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());Log.d(TAG, field.getName() +
" : " + field.get(
null));}
catch (Exception e) {Log.e(TAG,
"an error occured when collect crash info", e);}}}
/*** 保存錯誤信息到文件中** @param ex* @return 返回文件名稱,便于將文件傳送到服務器*/private String
saveCrashInfo2File(Throwable ex) {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();String result = writer.toString();sb.append(result);
try {
long timestamp = System.currentTimeMillis();String time = formatter.format(
new Date());String fileName =
"crash-" + time +
"-" + timestamp +
".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {String path =
"/sdcard/crash/";File dir =
new File(path);
if (!dir.exists()) {dir.mkdirs();}FileOutputStream fos =
new FileOutputStream(path + fileName);fos.write(sb.toString().getBytes());fos.close();}
return fileName;}
catch (Exception e) {Log.e(TAG,
"an error occured while writing file...", e);}
return null;}
}
2.定義自己的application類,進行異常處理CrashHandler 初始化
public class App extends Application {/*** 全局Application,方便調用*/public static App application;
public SharedPreferences SP;
public SharedPreferences.Editor EDIT;
public static List<Activity> list_activity;
public void onCreate() {
super.onCreate();application =
this;list_activity=
new ArrayList<Activity>();SP = getSharedPreferences(
"config", MODE_PRIVATE);EDIT = SP.edit();CrashHandler crashHandler = CrashHandler.getInstance();crashHandler.init(application);}
/*** 清空退款任務棧,需要在開啟每一個activity之后把其加入到list_activity集合中*/public static void RemoveActivity(){
if(!list_activity.isEmpty()){
for(Activity activity: list_activity){activity.finish();}}}}
3.清單文件中聲明自己的application類,添加這句話
android:name=”.自己的application類”
總結
以上是生活随笔為你收集整理的anddroid异常处理之UncaughtException的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。