第一步,重写UncaughtExceptionHandler类
public class UnCatchException implements UncaughtExceptionHandler { private UncaughtExceptionHandler mDefaultHandler; public static final String TAG = "CatchExcep"; private TuoPanApplication application; private Context mContext; private static Toast toast = null; public UnCatchException(TuoPanApplication application) { mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); mContext = application.getApplicationContext(); this.application = application; } @Override public void uncaughtException(Thread thread, Throwable ex) { String versioninfo = getVersionInfo(); String mobileInfo = getMobileInfo(); String errorinfo = getErrorInfo(ex); Log.e("CrashHandler", "errorinfo-->" + errorinfo); // 是发布版,并且还得运行输入错误日志到文件 if (Common.CRASH_FILE) { StringBuilder sb = new StringBuilder(); sb.append(mContext.getString(R.string.version_info, versioninfo)).append("\n") .append(mContext.getString(R.string.mobile_info, mobileInfo)).append("\n") .append(mContext.getString(R.string.error_info, errorinfo)); saveCrashInfo2File(sb.toString()); } if (!handleException(ex) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } else { try { Thread.sleep(2000); } catch (InterruptedException e) { Log.e(TAG, "error : ", e); } // if (Common.IS_RELOAD_APP) { // // Intent intent = new Intent(application.getApplicationContext(), SplashActivity.class); // PendingIntent restartIntent = PendingIntent.getActivity(mContext, 0, intent, // Intent.FLAG_ACTIVITY_NEW_TASK); // AlarmManager mgr = (AlarmManager) application.getSystemService(Context.ALARM_SERVICE); // mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // } application.finishAllActivity(); } } private boolean handleException(Throwable ex) { if (ex == null) { return false; } // new Thread() { // @Override // public void run() { // Looper.prepare(); // if (Common.IS_RELOAD_APP) { // showToast(mContext, mContext.getResources().getString(R.string.app_exception_notification), 1); // } else { // showToast(mContext, mContext.getResources().getString(R.string.app_exception_notification), 1); // } // Looper.loop(); // } // }.start(); return true; } // private static void showToast(Context context, String msg, int time) { // if (null != context) { // /** 自定义界面 */ // final LayoutInflater inflater = LayoutInflater.from(context); // View v = inflater.inflate(R.layout.toast_layout, null); // TextView iv = (TextView) v.findViewById(R.id.tv_toast); // if (!("".equals(msg))) { // if (toast == null) { // toast = new Toast(context); // iv.setText(msg); // toast.setDuration(time); // } else { // iv.setText(msg); // } // toast.setView(v); // toast.show(); // } // } // } /** * 获取错误的信 * * @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 = application.getApplicationContext().getPackageManager(); PackageInfo info = pm.getPackageInfo(application.getApplicationContext().getPackageName(), 0); return info.versionName; } catch (Exception e) { e.printStackTrace(); return application.getApplicationContext().getString(R.string.unknow_version); } } /** * 保存错误信息到文件中 * * @return 返回文件名称,便于将文件传送到服务 */ private String saveCrashInfo2File(String logMsg) { DateFormat formatter = new SimpleDateFormat("MM-dd-HH-mm-ss"); try { long timestamp = System.currentTimeMillis(); String time = formatter.format(new Date(timestamp)); String fileName = "log-" + time + ".log"; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (!fileExist(Common.LOGCATPATH, fileName)) { createFile(Common.LOGCATPATH, fileName); } FileOutputStream fos = new FileOutputStream(Common.LOGCATPATH + fileName); fos.write(logMsg.getBytes()); fos.close(); } return fileName; } catch (Exception e) { Log.e(TAG, "an error occured while writing file...", e); } return null; } /** * 由指定的路径和文件名创建文件 * * @param path * @param name * @return * @throws IOException */ public static File createFile(String path, String name) throws IOException { File folder = new File(path); if (!folder.exists()) { folder.mkdirs(); } File file = new File(path + name); if (!file.exists()) { file.createNewFile(); } return file; } /** * 判断文件是否存在 * * @param path * @param name * @return */ public static boolean fileExist(String path, String name) { File file = new File(path + name); if (file.exists() && !file.isDirectory()) { return true; } return false; } }
第二步,在application中oncreat方法里面配置
UnCatchException catchExcep = new UnCatchException(this); Thread.setDefaultUncaughtExceptionHandler(catchExcep);
另外添加一个日志管理工具
在开发中经常会反复用到一些功能,未节省时间,在此将常用到的一些工具进行总结:
Log日志打印
对于一个开发者来说,Log打印是必不可少的
/**
*
* 功能: 封装log ,以备发布Release时,关闭对应的 log 日志显示。只需调整LOG_LEVEL =0即可
* 使用:
*/
public class MyLog {
public static int LOG_LEVEL = 6;
public static int ERROR = 1;
public static int WARN = 2;
public static int INFO = 3;
public static int DEBUG = 4;
public static int VERBOS = 5;
public static void e(String tag,String msg){
if(LOG_LEVEL>ERROR)
Log.e(tag, msg);
}
public static void w(String tag,String msg){
if(LOG_LEVEL>WARN)
Log.w(tag, msg);
}
public static void i(String tag,String msg){
if(LOG_LEVEL>INFO)
Log.i(tag, msg);
}
public static void d(String tag,String msg){
if(LOG_LEVEL>DEBUG)
Log.d(tag, msg);
}
public static void v(String tag,String msg){
if(LOG_LEVEL>VERBOS)
Log.v(tag, msg);
}
}