Android Open Source - Common-Library Exception Catcher






From Project

Back to project page Common-Library.

License

The source code is released under:

Apache License

If you think the Android project Common-Library listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.morgan.library.snippet;
/*  w w  w  . j av  a  2  s  .c om*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Properties;
import java.util.TreeSet;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Looper;
import android.text.format.Time;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;

public class ExceptionCatcher implements UncaughtExceptionHandler {

  /** Debug Log tag */
  public static final String TAG = "CrashHandler";
  /**
   * ????????????,?Debug????????, ?Release????????????????
   * */
  public static final boolean DEBUG = false;
  /** ?????UncaughtException????? */
  private Thread.UncaughtExceptionHandler mDefaultHandler;
  /** CrashHandler?? */
  private static ExceptionCatcher INSTANCE;
  /** ????Context?? */
  private Context mContext;
  /** ??Properties?????????????????????? */
  private Properties mDeviceCrashInfo = new Properties();
  private static final String VERSION_NAME = "versionName";
  private static final String VERSION_CODE = "versionCode";
  private static final String STACK_TRACE = "STACK_TRACE";
  /** ???????????? */
  private static final String CRASH_REPORTER_EXTENSION = ".cr";

  /** ??????????CrashHandler?? */
  private ExceptionCatcher() {
  }

  /** ????CrashHandler?? ,??????? */
  public static ExceptionCatcher getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new ExceptionCatcher();
    }
    return INSTANCE;
  }

  /**
   * ????,??Context??, ?????????UncaughtException?????, ???CrashHandler????????????
   * 
   * @param ctx
   */
  public void init(Context ctx) {
    mContext = ctx;
    mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    Thread.setDefaultUncaughtExceptionHandler(this);
  }

  /**
   * ?UncaughtException??????????????????
   */
  @Override
  public void uncaughtException(Thread thread, Throwable ex) {
    if (!handleException(ex) && mDefaultHandler != null) {
      // ???????????????????????????????
      mDefaultHandler.uncaughtException(thread, ex);
    } else {
      // Sleep????????????
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        Log.e(TAG, "Error : ", e);
      }
      android.os.Process.killProcess(android.os.Process.myPid());
      System.exit(10);
    }
  }

  /**
   * ?????????,???????? ?????????????????????. ????????????????????????????????
   * 
   * @param ex
   * @return true:??????????????;??????false
   */
  private boolean handleException(Throwable ex) {
    if (ex == null) {
      Log.w(TAG, "handleException --- ex==null");
      return true;
    }
    final String msg = ex.getLocalizedMessage();
    if (msg == null) {
      return false;
    }
    // ??Toast???????????
    new Thread() {
      @Override
      public void run() {
        Looper.prepare();
        Toast toast = Toast.makeText(mContext, "????????????:\r\n" + msg,
            Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
        // MsgPrompt.showMsg(mContext, "??????", msg+"\n?????");
        Looper.loop();
      }
    }.start();
    // ????????
    collectCrashDeviceInfo(mContext);
    // ?????????
    saveCrashInfoToFile(ex);
    // ??????????????
    sendCrashReportsToServer(mContext);
    return true;
  }

  /**
   * ??????????, ??????????????????????????????
   */
  public void sendPreviousReportsToServer() {
    sendCrashReportsToServer(mContext);
  }

  /**
   * ???????????????,???????????????????.
   * 
   * @param ctx
   */
  private void sendCrashReportsToServer(Context ctx) {
    String[] crFiles = getCrashReportFiles(ctx);
    if (crFiles != null && crFiles.length > 0) {
      TreeSet<String> sortedFiles = new TreeSet<String>();
      sortedFiles.addAll(Arrays.asList(crFiles));
      for (String fileName : sortedFiles) {
        File cr = new File(ctx.getFilesDir(), fileName);
        postReport(cr);
        cr.delete();// ???????????
      }
    }
  }

  private void postReport(File file) {
    // TODO ??????????????
  }

  /**
   * ?????????????
   * 
   * @param ctx
   * @return
   */
  private String[] getCrashReportFiles(Context ctx) {
    File filesDir = ctx.getFilesDir();
    FilenameFilter filter = new FilenameFilter() {
      public boolean accept(File dir, String name) {
        return name.endsWith(CRASH_REPORTER_EXTENSION);
      }
    };
    return filesDir.list(filter);
  }

  /**
   * ?????????????
   * 
   * @param ex
   * @return
   */
  private String saveCrashInfoToFile(Throwable ex) {
    Writer info = new StringWriter();
    PrintWriter printWriter = new PrintWriter(info);
    ex.printStackTrace(printWriter);
    Throwable cause = ex.getCause();
    while (cause != null) {
      cause.printStackTrace(printWriter);
      cause = cause.getCause();
    }
    String result = info.toString();
    printWriter.close();
    mDeviceCrashInfo.put("EXEPTION", ex.getLocalizedMessage());
    mDeviceCrashInfo.put(STACK_TRACE, result);
    try {
      // long timestamp = System.currentTimeMillis();
      Time t = new Time("GMT+8");
      t.setToNow(); // ????????
      int date = t.year * 10000 + t.month * 100 + t.monthDay;
      int time = t.hour * 10000 + t.minute * 100 + t.second;
      String fileName = "crash-" + date + "-" + time
          + CRASH_REPORTER_EXTENSION;
      FileOutputStream trace = mContext.openFileOutput(fileName,
          Context.MODE_PRIVATE);
      mDeviceCrashInfo.store(trace, "");
      trace.flush();
      trace.close();
      return fileName;
    } catch (Exception e) {
      Log.e(TAG, "an error occured while writing report file...", e);
    }
    return null;
  }

  /**
   * ??????????????
   * 
   * @param ctx
   */
  public void collectCrashDeviceInfo(Context ctx) {
    try {
      PackageManager pm = ctx.getPackageManager();
      PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
          PackageManager.GET_ACTIVITIES);
      if (pi != null) {
        mDeviceCrashInfo.put(VERSION_NAME,
            pi.versionName == null ? "not set" : pi.versionName);
        mDeviceCrashInfo.put(VERSION_CODE, "" + pi.versionCode);
      }
    } catch (NameNotFoundException e) {
      Log.e(TAG, "Error while collect package info", e);
    }
    // ?????????????????.?Build?????????????????,
    // ??: ???????,????? ???????????????
    // ????????????????????
    Field[] fields = Build.class.getDeclaredFields();
    for (Field field : fields) {
      try {
        field.setAccessible(true);
        mDeviceCrashInfo.put(field.getName(), "" + field.get(null));
        if (DEBUG) {
          Log.d(TAG, field.getName() + " : " + field.get(null));
        }
      } catch (Exception e) {
        Log.e(TAG, "Error while collect crash info", e);
      }
    }
  }

}




Java Source Code List

com.morgan.library.app.APPContext.java
com.morgan.library.app.AppManager.java
com.morgan.library.app.BaseActivity.java
com.morgan.library.app.BaseFragmentActivity.java
com.morgan.library.app.BaseListActivity.java
com.morgan.library.app.BaseScreenShotActivity.java
com.morgan.library.app.CommonApplication.java
com.morgan.library.async.CustomAsyncTask.java
com.morgan.library.async.Destroyable.java
com.morgan.library.async.IFeedback.java
com.morgan.library.async.TaskManager.java
com.morgan.library.model.NetResult.java
com.morgan.library.model.SpinnerItem.java
com.morgan.library.model.WeatherType.java
com.morgan.library.model.Weather.java
com.morgan.library.net.ApiClient.java
com.morgan.library.net.ApiManager.java
com.morgan.library.net.ApiUrl.java
com.morgan.library.net.IApiClient.java
com.morgan.library.net.JsonUtils.java
com.morgan.library.net.MockApiClient.java
com.morgan.library.service.LocationManager.java
com.morgan.library.service.WeatherManager.java
com.morgan.library.snippet.CookieShare.java
com.morgan.library.snippet.CustomService.java
com.morgan.library.snippet.ExceptionCatcher.java
com.morgan.library.snippet.ProxyUsage.java
com.morgan.library.snippet.SocketClient.java
com.morgan.library.snippet.SocketServer.java
com.morgan.library.snippet.UDPClient.java
com.morgan.library.snippet.UDPServer.java
com.morgan.library.snippet.XMLAnalyze.java
com.morgan.library.task.GetWeatherTask.java
com.morgan.library.utils.AppUtils.java
com.morgan.library.utils.DateUtils.java
com.morgan.library.utils.DensityUtils.java
com.morgan.library.utils.FileUtils.java
com.morgan.library.utils.GB2Alpha.java
com.morgan.library.utils.HttpClientUtil.java
com.morgan.library.utils.HttpClientUtils.java
com.morgan.library.utils.HttpURLUtil.java
com.morgan.library.utils.ImageUtils.java
com.morgan.library.utils.KeyBoardUtils.java
com.morgan.library.utils.LocationUtils.java
com.morgan.library.utils.Logger.java
com.morgan.library.utils.NetUtils.java
com.morgan.library.utils.PhoneUtils.java
com.morgan.library.utils.SDCardUtils.java
com.morgan.library.utils.StrUtils.java
com.morgan.library.widget.AutoHideMenuWidget.java
com.morgan.library.widget.BadgeView.java
com.morgan.library.widget.CityPickerWidget.java
com.morgan.library.widget.CustomGridView.java
com.morgan.library.widget.CustomListView.java
com.morgan.library.widget.CustomToast.java
com.morgan.library.widget.CustomViewPager.java
com.morgan.library.widget.DatePickerWidget.java
com.morgan.library.widget.DirectionScrollView.java
com.morgan.library.widget.FallBallView.java
com.morgan.library.widget.HeightPickerWidget.java
com.morgan.library.widget.InterceptPressLayout.java
com.morgan.library.widget.ItalicTextView.java
com.morgan.library.widget.PopupMenuWidget.java
com.morgan.library.widget.PullToRefreshListView.java
com.morgan.library.widget.ScreenShotView.java
com.morgan.library.widget.SexPickerWidget.java
com.morgan.library.widget.SlideUpOpenWidget.java
com.morgan.library.widget.SwipeListView.java
com.morgan.library.widget.TimePickerWidget.java
com.morgan.library.widget.TouchZoomImageView.java
com.morgan.library.widget.WaitScreenWidget.java
com.morgan.library.widget.WebViewDialog.java
com.morgan.library.widget.WeightPickerWidget.java
com.morgan.library.widget.calendar.CalendarGridView.java
com.morgan.library.widget.calendar.CalendarScrollView.java
com.morgan.library.widget.calendar.CalendarViewFlipper.java
com.morgan.library.widget.calendar.CalendarWidget.java
com.morgan.library.widget.numberpicker.NumberPicker.java
com.morgan.library.widget.numberpicker.Scroller.java
com.morgan.library.widget.slidemenu.ScrollDetectorFactory.java
com.morgan.library.widget.slidemenu.ScrollDetectors.java
com.morgan.library.widget.slidemenu.SlideMenu.java