当程序崩溃(Crash)的时候,默认是不对异常信息做处理的。如果想要把异常信息保存到本地文件中,或上传的服务器。那么就要借助UncaughtExceptionHandler这个类。
首先,实例化UncaughtExceptionHandler,代码如下:
public class ForceCloseHandler implements Thread.UncaughtExceptionHandler { public static final String LOG_FILE_NAME = "forceclose.log"; private static ForceCloseHandler inst ; public static ForceCloseHandler getInstance() { if(inst==null)inst = new ForceCloseHandler(); return inst; } private Context mContext; private Thread.UncaughtExceptionHandler mExceptionHandler; private JSONObject jsonObject; private ForceCloseHandler() {} public void init(Context context) { mContext = context; mExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } private void handleUncaughtException(Throwable ex) { if (ex == null) return; try { if(jsonObject ==null)jsonObject = new JSONObject(); saveDeviceInfo(); saveForceCloseInfo2File(ex); // 把异常信息发送到服务器 ForceCloseFeedBack.getInstance().feedBack(mContext, jsonObject.toString()); } catch (Exception e) { LogUtil.w(e); } } @Override public void uncaughtException(Thread thread, Throwable throwable) { handleUncaughtException(throwable); if (throwable != null) LogUtil.w(throwable); mExceptionHandler.uncaughtException(thread, throwable); } public void saveDeviceInfo() throws JSONException { TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); jsonObject.put("platform", "android"); jsonObject.put("model", Build.MODEL); jsonObject.put("trackid", AppConfig.PARTNER_ID); jsonObject.put("product", AppConfig.CLIENT_TAG); jsonObject.put("os_version", Build.VERSION.RELEASE); jsonObject.put("deviceid", DeviceInfo.getDeviceId()); jsonObject.put("net_type", tm.getNetworkOperator()); jsonObject.put("timestamp", System.currentTimeMillis()); jsonObject.put("app_version", Application.getInstance().getVersionCode()); } private void saveForceCloseInfo2File(Throwable ex) throws Exception { StringWriter 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() + "\n"; jsonObject.put("errorDetail", result); if (AppConfig.LOG_ERR_SAVE) { File file = FileHelper.getDiskCacheDir(mContext, LOG_FILE_NAME); FileOutputStream fos = new FileOutputStream(file, true); fos.write(jsonObject.toString().getBytes()); fos.close(); } } }接下来,看看这个实例化后的类怎么使用,代码如下:
public class Application extends android.app.Application { private static Application instance; public Context currentContext; public static Application getInstance() { return instance; } @Override public void onCreate() { super.onCreate(); init(); } public void init() { instance = this; if (Config.LOG_ERR_FEED) { ForceCloseHandler.getInstance().init(instance); } } @Override public void onTerminate() { super.onTerminate(); } @Override public void onLowMemory() { super.onLowMemory(); } }非常简单,只要在指定的Application类的onCreate()回调中,把UncaughtExceptionHandler和Application的实例绑定在一起就可以了。关键代码如下:
public void init(Context context) { mContext = context; mExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); }这样,如果程序崩溃,错误日志就会被保存在本地,同时又被上传到了服务器。