在使用APP的过程中,任何时候都可能遇到异常,能够预判到的异常只是极少数,对于不能预判到的异常,可以统一利用UncaughtExceptionHandler接口类处理。如果子线程中出现异常,在主线程代码中使用try…catch…是无法捕获到异常的,必须使用UncaughtExceptionHandler来进行处理。在实现UncaughtExceptionHandler接口类的函数时,必须重载uncaughtException(Threadthread,Throwableex)函数。如下代码利用UncaughtExceptionHandler接口类处理异常,并保存异常日志到本机。
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; // 用来 存储 设备 信息 和 异常 信息 private Map< String, String> info = new HashMap< String, String>(); private SimpleDateFormat format = new SimpleDateFormat(" yyyy- MM- dd- HH- mm- ss"); private rwUncaughtExceptionHandler() { } // 获取 rwUncaughtExceptionHandler 实例 public static rwUncaughtExceptionHandler getInstance() { return INSTANCE; } public void init( Context context){ mContext = context; // 获取 系统 默认 的 UncaughtException 处理 句柄 mDefaultHandler = Thread. getDefaultUncaughtExceptionHandler(); // 设置 该 rwUncaughtExceptionHandler 为 APP 的 默认 处理 句柄 Thread. setDefaultUncaughtExceptionHandler( this); } @ Override public 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); } 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 秒钟 后 重 启 应用 restartIntent); //关闭 所有 的 Activity exceptionHandlerApplication. finishActivity(); } } /** * 自定义 异常 处理、 收集 异常 信息 和 保存 数据 到 本机 * * @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, "很 抱歉, 程序 出现 异常, 即将 退出 并重 启。", Toast. LENGTH_ SHORT). show(); Looper. loop(); } }. start(); // 收集 设备 参数 信息 collectDeviceInfo( mContext); // 保存 日志 文件 saveCrashInfo( ex); return true; }
/** * 收集 APP 版本 信息 和 设备 参数 信息 * * @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(" 手机 型号:", android. os. Build. MODEL); info. put(" 系统 版本", ""+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); // 把 数据 保存 到 文件 里 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开发公司本文关于“APP开发怎样解决使用try…catch…处理异常?”的处理方法与流程本文就分享到这里,谢谢关注,博纳网络编辑整理。