在使用APP的過程中,任何時候都可能遇到異常,能夠預(yù)判到的異常只是極少數(shù),對于不能預(yù)判到的異常,可以統(tǒng)一利用UncaughtExceptionHandler接口類處理。如果子線程中出現(xiàn)異常,在主線程代碼中使用try…catch…是無法捕獲到異常的,必須使用UncaughtExceptionHandler來進(jìn)行處理。在實(shí)現(xiàn)UncaughtExceptionHandler接口類的函數(shù)時,必須重載uncaughtException(Threadthread,Throwableex)函數(shù)。如下代碼利用UncaughtExceptionHandler接口類處理異常,并保存異常日志到本機(jī)。
public class rwUncaughtExceptionHandler implements Thread. UncaughtExceptionHandler { private Thread. UncaughtExceptionHandler mDefaultHandler; public static final String TAG = "rwUncaught"; private static rwUncaughtExceptionHandler INSTANCE = new rwUncaughtExceptionHandler(); private Context mContext; // 用來 存儲 設(shè)備 信息 和 異常 信息 private Map< String, String> info = new HashMap< String, String>(); private SimpleDateFormat format = new SimpleDateFormat(" yyyy- MM- dd- HH- mm- ss"); private rwUncaughtExceptionHandler() { } // 獲取 rwUncaughtExceptionHandler 實(shí)例 public static rwUncaughtExceptionHandler getInstance() { return INSTANCE; } public void init( Context context){ mContext = context; // 獲取 系統(tǒng) 默認(rèn) 的 UncaughtException 處理 句柄 mDefaultHandler = Thread. getDefaultUncaughtExceptionHandler(); // 設(shè)置 該 rwUncaughtExceptionHandler 為 APP 的 默認(rèn) 處理 句柄 Thread. setDefaultUncaughtExceptionHandler( this); } @ Override public void uncaughtException( Thread thread, Throwable ex) { if (!handleException( ex) && mDefaultHandler != null) { // 如果 用戶 沒有 處理 則 調(diào)用 系統(tǒng) 默認(rèn) 的 異常 處理 句柄 來 處理 mDefaultHandler. uncaughtException( thread, ex); } else { try { Thread. sleep( 2000);
} catch (InterruptedException e) { Log. e( TAG, "error : ", e); } Intent intent = new Intent( mContext. getApplicationContext(), ViewPagerDemo. class); PendingIntent restartIntent = PendingIntent. getActivity (mContext. getApplicationContext(), 0, intent. addFlags( Intent. FLAG_ ACTIVITY_ NEW_ TASK), 0); AlarmManager mgr = (AlarmManager) mContext. getSystemService (Context. ALARM_ SERVICE); mgr. set( AlarmManager. RTC, System. currentTimeMillis() + 1000, // 1 秒鐘 后 重 啟 應(yīng)用 restartIntent); //關(guān)閉 所有 的 Activity exceptionHandlerApplication. finishActivity(); } } /** * 自定義 異常 處理、 收集 異常 信息 和 保存 數(shù)據(jù) 到 本機(jī) * * @param ex
* @return true: 如果 處理 了 該 異常 信息 返回 true; 否則 返回 false. */ private boolean handleException( Throwable ex) { if (ex == null) { return false; } // 使用 Toast 來 顯示 異常 信息 new Thread() { @ Override public void run() { Looper. prepare(); Toast. makeText( mContext, "很 抱歉, 程序 出現(xiàn) 異常, 即將 退出 并重 啟。", Toast. LENGTH_ SHORT). show(); Looper. loop(); } }. start(); // 收集 設(shè)備 參數(shù) 信息 collectDeviceInfo( mContext); // 保存 日志 文件 saveCrashInfo( ex); return true; }
/** * 收集 APP 版本 信息 和 設(shè)備 參數(shù) 信息 * * @param context */ public void collectDeviceInfo( Context context) { try { PackageManager pm = context. getPackageManager(); PackageInfo pi = pm. getPackageInfo( context. getPackageName(), PackageManager. GET_ ACTIVITIES); if (pi != null) { String versionName = pi. versionName == null ? "null" : pi. versionName; String versionCode = pi. versionCode + ""; info. put(" versionName", versionName); info. put(" versionCode", versionCode); info. put(" 手機(jī) 型號:", android. os. Build. MODEL); info. put(" 系統(tǒng) 版本", ""+android. os. Build. VERSION. SDK); info. put(" Android 版本", android. os. Build. VERSION. RELEASE); } } catch (PackageManager. NameNotFoundException e) { e. printStackTrace(); }
Field[] fields = Build. class. getDeclaredFields(); for (Field field : fields) { try { field. setAccessible( true); info. put( field. getName(), field. get(""). toString()); Log. d( TAG, field. getName() + ":" + field. get("")); } catch (IllegalArgumentException e) { e. printStackTrace(); } catch (IllegalAccessException e) { e. printStackTrace(); } } } private String saveCrashInfo( Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map. Entry< String, String> entry : info. entrySet()) { String key = entry. getKey(); String value = entry. getValue(); sb. append( key + "=" + value + "\r\ n"); } Writer writer = new StringWriter(); PrintWriter pw = new PrintWriter( writer); ex. printStackTrace( pw);
Throwable cause = ex. getCause(); while (cause != null) { cause. printStackTrace( pw); cause = cause. getCause(); } pw. close(); String result = writer. toString(); sb. append( result); // 把 數(shù)據(jù) 保存 到 文件 里 long timetamp = System. currentTimeMillis(); String time = format. format( new Date()); String fileName = "crash_" + time + "_"+ ".log"; if (Environment. getExternalStorageState(). equals( Environment. MEDIA_ MOUNTED)) { try { File dir = new File( Environment. getExternalStorageDirectory(). getAbsolutePath() + File. separator + "crash"); Log. i(" CrashHandler", dir. toString()); if (!dir. exists()) dir. mkdir(); FileOutputStream fos = new FileOutputStream( new File( dir, fileName));
fos. write( sb. toString(). getBytes()); fos. close(); return fileName; } catch (FileNotFoundException e) { e. printStackTrace(); } catch (IOException e) { e. printStackTrace(); } } return null; } }
好了,
APP開發(fā)公司本文關(guān)于“APP開發(fā)怎樣解決使用try…catch…處理異常?”的處理方法與流程本文就分享到這里,謝謝關(guān)注,博納網(wǎng)絡(luò)編輯整理。