一个已发布的APP怎么搜集一些bug信息呢?

下面是一个捕获全局异常并输出到日志文件的类(没有将bug日志上传服务器部分,可自行添加)

public class CrashHandlerUtil implements UncaughtExceptionHandler {        public static final String TAG = "CrashHandler";        // CrashHandler 实例      private static CrashHandlerUtil INSTANCE = new CrashHandlerUtil();        // 程序的 Context 对象      private Context mContext;        // 系统默认的 UncaughtException 处理类      private Thread.UncaughtExceptionHandler mDefaultHandler;        // 用来存储设备信息和异常信息      private Map<String, String> infos = new HashMap<String, String>();        // 用于格式化日期,作为日志文件名的一部分      @SuppressLint("SimpleDateFormat")private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");          /** 保证只有一个 CrashHandler 实例 */      private CrashHandlerUtil() {      }        /** 获取 CrashHandler 实例 ,单例模式 */      public static CrashHandlerUtil getInstance() {          return INSTANCE;      }        /**      * 初始化      *      * @param context      */      public void init(Context context) {          mContext = context;                // 获取系统默认的 UncaughtException 处理器          mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();                // 设置该 CrashHandler 为程序的默认处理器          Thread.setDefaultUncaughtExceptionHandler(this);      }        /**      * 当 UncaughtException 发生时会转入该函数来处理      */      @Override      public void uncaughtException(Thread thread, Throwable ex) {          if (!handleException(ex) && mDefaultHandler != null) {              // 如果用户没有处理则让系统默认的异常处理器来处理              mDefaultHandler.uncaughtException(thread, ex);          } else {              try {                  Thread.sleep(3000);              } catch (InterruptedException e) {                  Log.e(TAG, "error : ", e);              }                // 退出程序,注释下面的重启启动程序代码            android.os.Process.killProcess(android.os.Process.myPid());              System.exit(-1);             // 重新启动程序,注释上面的退出程序           /*Intent intent = new Intent();           intent.setClass(mContext,BaseActivity.class);           intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);           mContext.startActivity(intent);           android.os.Process.killProcess(android.os.Process.myPid());*/        }      }        /**      * 自定义错误处理,收集错误信息,发送错误报告等操作均在此完成      *       * @param ex      * @return true:如果处理了该异常信息;否则返回 false      */      private boolean handleException(Throwable ex) {          if (ex == null) {              return false;          }              // 收集设备参数信息          collectDeviceInfo(mContext);          // 保存日志文件          saveCrashInfo2File(ex);        return true;      }        /**      * 收集设备参数信息      * @param ctx      */      public void collectDeviceInfo(Context ctx) {          try {              PackageManager pm = ctx.getPackageManager();              PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);                if (pi != null) {                  String versionName = pi.versionName == null ? "null" : pi.versionName;                  String versionCode = pi.versionCode + "";                  infos.put("versionName", versionName);                  infos.put("versionCode", versionCode);              }          } catch (NameNotFoundException e) {              Log.e(TAG, "an error occured when collect package info", e);          }            Field[] fields = Build.class.getDeclaredFields();          for (Field field : fields) {              try {                  field.setAccessible(true);                  infos.put(field.getName(), field.get(null).toString());                  Log.d(TAG, field.getName() + " : " + field.get(null));              } catch (Exception e) {                  Log.e(TAG, "an error occured when collect crash info", e);              }          }      }        /**      * 保存错误信息到文件中     *      * @param ex      * @return  返回文件名称,便于将文件传送到服务器      */      private String saveCrashInfo2File(Throwable ex) {           String time = formatter.format(new Date());          StringBuffer sb = new StringBuffer();         sb.append(time+"\n");        for (Map.Entry<String, String> entry : infos.entrySet()) {  //设备信息            String key = entry.getKey();              String value = entry.getValue();              sb.append(key + "=" + value + "\n");          }          Writer 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();          sb.append(result+"\n");          try {                          String fileName = "error.log";             if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {                  String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator+"crash/";                  File dir = new File(path);                  if (!dir.exists()) {                      dir.mkdirs();                  }                File file=new File(path+fileName);                if(!file.exists()){                file.createNewFile();                }                FileOutputStream fos = new FileOutputStream(path+fileName, true);                 fos.write(sb.toString().getBytes());                  fos.close();              }                return fileName;          } catch (Exception e) {              Log.e(TAG, "an error occured while writing file...", e);          }            return null;      }  }

更多相关文章

  1. Android(安卓)NDK Log信息打印
  2. google Android编译本地C++程序方法
  3. 【Android】原生安装和卸载应用
  4. Android消息提示框
  5. 【Android】结束活动退出程序的方法
  6. 安卓开发:学生信息管理小程序
  7. Android(安卓)Handler的使用!!!
  8. Android中获取应用程序(包)的大小-----PackageManager的使用(二)
  9. android 内存占用 分析工具

随机推荐

  1. Appium API
  2. Android开发整理
  3. saaaaaaaaa
  4. Android(安卓)studio 导入github工程
  5. Android(安卓)获取View高度宽度
  6. android_lesson_2
  7. [置顶] android Properties的使用
  8. WebViewJavascriptBridge实现js与android
  9. android自带Base64加密解密
  10. Android再次按back键退出