捕获异常信息_UncaughtExceptionHandler,保存日志到本地及发送服务器

当程序崩溃(Crash)的时候,默认是不对异常信息做处理的。如果想要把异常信息保存到本地文件中,或上传的服务器。那么就要借助UncaughtExceptionHandler这个类。

首先,实例化UncaughtExceptionHandler,代码如下:

[java]  view plain  copy
  1. public class ForceCloseHandler implements Thread.UncaughtExceptionHandler {  
  2.   
  3.     public static final String LOG_FILE_NAME = "forceclose.log";  
  4.   
  5.     private static ForceCloseHandler inst ;  
  6.     public static ForceCloseHandler getInstance() {  
  7.         if(inst==null)inst = new ForceCloseHandler();  
  8.         return inst;  
  9.     }  
  10.   
  11.   
  12.     private Context mContext;  
  13.     private Thread.UncaughtExceptionHandler mExceptionHandler;  
  14.     private JSONObject jsonObject;  
  15.     private ForceCloseHandler() {}  
  16.   
  17.     public void init(Context context) {  
  18.         mContext = context;  
  19.         mExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();  
  20.         Thread.setDefaultUncaughtExceptionHandler(this);  
  21.     }  
  22.   
  23.   
  24.     private void handleUncaughtException(Throwable ex) {  
  25.         if (ex == nullreturn;  
  26.         try {  
  27.             if(jsonObject ==null)jsonObject = new JSONObject();  
  28.             saveDeviceInfo();  
  29.             saveForceCloseInfo2File(ex);  
  30.             // 把异常信息发送到服务器  
  31.             ForceCloseFeedBack.getInstance().feedBack(mContext, jsonObject.toString());  
  32.         } catch (Exception e) {  
  33.             LogUtil.w(e);  
  34.         }  
  35.     }  
  36.   
  37.     @Override  
  38.     public void uncaughtException(Thread thread, Throwable throwable) {  
  39.         handleUncaughtException(throwable);  
  40.         if (throwable != null) LogUtil.w(throwable);  
  41.         mExceptionHandler.uncaughtException(thread, throwable);  
  42.     }  
  43.   
  44.     public void saveDeviceInfo() throws JSONException {  
  45.         TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);  
  46.   
  47.         jsonObject.put("platform""android");  
  48.         jsonObject.put("model", Build.MODEL);  
  49.         jsonObject.put("trackid", AppConfig.PARTNER_ID);  
  50.         jsonObject.put("product", AppConfig.CLIENT_TAG);  
  51.         jsonObject.put("os_version", Build.VERSION.RELEASE);  
  52.         jsonObject.put("deviceid", DeviceInfo.getDeviceId());  
  53.         jsonObject.put("net_type", tm.getNetworkOperator());  
  54.         jsonObject.put("timestamp", System.currentTimeMillis());  
  55.         jsonObject.put("app_version", Application.getInstance().getVersionCode());  
  56.     }  
  57.   
  58.     private void saveForceCloseInfo2File(Throwable ex) throws Exception {  
  59.         StringWriter writer = new StringWriter();  
  60.         PrintWriter printWriter = new PrintWriter(writer);  
  61.         ex.printStackTrace(printWriter);  
  62.         Throwable cause = ex.getCause();  
  63.         while (cause != null) {  
  64.             cause.printStackTrace(printWriter);  
  65.             cause = cause.getCause();  
  66.         }  
  67.         printWriter.close();  
  68.         String result = writer.toString() + "\n";  
  69.         jsonObject.put("errorDetail", result);  
  70.   
  71.         if (AppConfig.LOG_ERR_SAVE) {  
  72.             File file = FileHelper.getDiskCacheDir(mContext, LOG_FILE_NAME);  
  73.             FileOutputStream fos = new FileOutputStream(file, true);  
  74.             fos.write(jsonObject.toString().getBytes());  
  75.             fos.close();  
  76.         }  
  77.     }  
  78.   
  79. }  
接下来,看看这个实例化后的类怎么使用,代码如下:

[java]  view plain  copy
  1. public class Application extends android.app.Application {  
  2.   
  3.     private static Application instance;  
  4.   
  5.     public Context currentContext;  
  6.   
  7.     public static Application getInstance() {  
  8.         return instance;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void onCreate() {  
  13.         super.onCreate();  
  14.         init();  
  15.     }  
  16.   
  17.     public void init() {  
  18.         instance = this;  
  19.   
  20.         if (Config.LOG_ERR_FEED) {   
  21.             ForceCloseHandler.getInstance().init(instance);  
  22.         }  
  23.     }  
  24.   
  25.     @Override  
  26.     public void onTerminate() {  
  27.         super.onTerminate();  
  28.     }  
  29.   
  30.     @Override  
  31.     public void onLowMemory() {  
  32.         super.onLowMemory();  
  33.     }  
  34.   
  35. }  
非常简单,只要在指定的Application类的onCreate()回调中,把UncaughtExceptionHandler和Application的实例绑定在一起就可以了。关键代码如下:
[java]  view plain  copy
  1. public void init(Context context) {  
  2.     mContext = context;  
  3.     mExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();  
  4.     Thread.setDefaultUncaughtExceptionHandler(this);  
  5. }  
这样,如果程序崩溃,错误日志就会被保存在本地,同时又被上传到了服务器。

你可能感兴趣的:(捕获异常信息_UncaughtExceptionHandler,保存日志到本地及发送服务器)