不学网

 找回密码
 立即注册

手机号码,快捷登录

查看: 408|回复: 0

[java] android中app异常java部分处理

[复制链接]
rain1994 发表于 2018-6-30 17:36:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
1.新建类CrashHandler来处理异常
  1. /**
  2. * <h3>全局捕获异常</h3>
  3. * <br>
  4. * 当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误日志
  5. *  
  6. */  
  7. @SuppressLint("SimpleDateFormat")  
  8. public class CrashHandler implements UncaughtExceptionHandler {  
  9.   
  10.     public static String TAG = "MyCrash";  
  11.     // 系统默认的UncaughtException处理类  
  12.     private Thread.UncaughtExceptionHandler mDefaultHandler;  
  13.   
  14.     private static CrashHandler instance = new CrashHandler();  
  15.     private Context mContext;  
  16.   
  17.     // 用来存储设备信息和异常信息  
  18.     private Map<String, String> infos = new HashMap<String, String>();  
  19.   
  20.     // 用于格式化日期,作为日志文件名的一部分  
  21.     private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");  
  22.   
  23.     /** 保证只有一个CrashHandler实例 */  
  24.     private CrashHandler() {  
  25.     }  
  26.   
  27.     /** 获取CrashHandler实例 ,单例模式 */  
  28.     public static CrashHandler getInstance() {  
  29.         return instance;  
  30.     }  
  31.   
  32.     /**
  33.      * 初始化
  34.      *  
  35.      * @param context
  36.      */  
  37.     public void init(Context context) {  
  38.         mContext = context;  
  39.         // 获取系统默认的UncaughtException处理器  
  40.         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  
  41.         // 设置该CrashHandler为程序的默认处理器  
  42.         Thread.setDefaultUncaughtExceptionHandler(this);  
  43.         autoClear(5);  
  44.     }  
  45.   
  46.     /**
  47.      * 当UncaughtException发生时会转入该函数来处理
  48.      */  
  49.     @Override  
  50.     public void uncaughtException(Thread thread, Throwable ex) {  
  51.         if (!handleException(ex) && mDefaultHandler != null) {  
  52.             // 如果用户没有处理则让系统默认的异常处理器来处理  
  53.             mDefaultHandler.uncaughtException(thread, ex);  
  54.         } else {  
  55.             SystemClock.sleep(3000);  
  56.             // 退出程序  
  57.             android.os.Process.killProcess(android.os.Process.myPid());  
  58.             System.exit(1);  
  59.         }  
  60.     }  
  61.   
  62.     /**
  63.      * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
  64.      *  
  65.      * @param ex
  66.      * @return true:如果处理了该异常信息; 否则返回false.
  67.      */  
  68.     private boolean handleException(Throwable ex) {  
  69.         if (ex == null)  
  70.             return false;  
  71.   
  72.         try {  
  73.             // 使用Toast来显示异常信息  
  74.             new Thread() {  
  75.   
  76.                 @Override  
  77.                 public void run() {  
  78.                     Looper.prepare();  
  79.                     Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.",  
  80.                             Toast.LENGTH_LONG).show();  
  81.                     Looper.loop();  
  82.                 }  
  83.             }.start();  
  84.             // 收集设备参数信息  
  85.             collectDeviceInfo(mContext);  
  86.             // 保存日志文件  
  87.             saveCrashInfoFile(ex);  
  88.             SystemClock.sleep(3000);  
  89.         } catch (Exception e) {  
  90.             e.printStackTrace();  
  91.         }  
  92.   
  93.         return true;  
  94.     }  
  95.   
  96.     /**
  97.      * 收集设备参数信息
  98.      *  
  99.      * @param ctx
  100.      */  
  101.     public void collectDeviceInfo(Context ctx) {  
  102.         try {  
  103.             PackageManager pm = ctx.getPackageManager();  
  104.             PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),  
  105.                     PackageManager.GET_ACTIVITIES);  
  106.             if (pi != null) {  
  107.                 String versionName = pi.versionName + "";  
  108.                 String versionCode = pi.versionCode + "";  
  109.                 infos.put("versionName", versionName);  
  110.                 infos.put("versionCode", versionCode);  
  111.             }  
  112.         } catch (NameNotFoundException e) {  
  113.             Log.e(TAG, "an error occured when collect package info", e);  
  114.         }  
  115.         Field[] fields = Build.class.getDeclaredFields();  
  116.         for (Field field : fields) {  
  117.             try {  
  118.                 field.setAccessible(true);  
  119.                 infos.put(field.getName(), field.get(null).toString());  
  120.             } catch (Exception e) {  
  121.                 Log.e(TAG, "an error occured when collect crash info", e);  
  122.             }  
  123.         }  
  124.     }  
  125.   
  126.     /**
  127.      * 保存错误信息到文件中
  128.      * @param ex
  129.      * @return 返回文件名称,便于将文件传送到服务器
  130.      * @throws Exception
  131.      */  
  132.     private String saveCrashInfoFile(Throwable ex) throws Exception {  
  133.         StringBuffer sb = new StringBuffer();  
  134.         try {  
  135.             SimpleDateFormat sDateFormat = new SimpleDateFormat(  
  136.                     "yyyy-MM-dd HH:mm:ss");  
  137.             String date = sDateFormat.format(new java.util.Date());  
  138.             sb.append("\r\n" + date + "\n");  
  139.             for (Map.Entry<String, String> entry : infos.entrySet()) {  
  140.                 String key = entry.getKey();  
  141.                 String value = entry.getValue();  
  142.                 sb.append(key + "=" + value + "\n");  
  143.             }  
  144.   
  145.             Writer writer = new StringWriter();  
  146.             PrintWriter printWriter = new PrintWriter(writer);  
  147.             ex.printStackTrace(printWriter);  
  148.             Throwable cause = ex.getCause();  
  149.             while (cause != null) {  
  150.                 cause.printStackTrace(printWriter);  
  151.                 cause = cause.getCause();  
  152.             }  
  153.             printWriter.flush();  
  154.             printWriter.close();  
  155.             String result = writer.toString();  
  156.             sb.append(result);  
  157.   
  158.             String fileName = writeFile(sb.toString());  
  159.             return fileName;  
  160.         } catch (Exception e) {  
  161.             Log.e(TAG, "an error occured while writing file...", e);  
  162.             sb.append("an error occured while writing file...\r\n");  
  163.             writeFile(sb.toString());  
  164.         }  
  165.         return null;  
  166.     }  
  167.   
  168.     private String writeFile(String sb) throws Exception {  
  169.         String time = formatter.format(new Date());  
  170.         String fileName = "crash-" + time + ".log";  
  171.                 String path = getGlobalpath();  
  172.         File dir = new File(path);  
  173.         if (!dir.exists())  
  174.             dir.mkdirs();  
  175.         FileOutputStream fos = new FileOutputStream(path + fileName, true);  
  176.         fos.write(sb.getBytes());  
  177.         fos.flush();  
  178.         fos.close();  
  179.         return fileName;  
  180.     }  
  181.   
  182.     public static String getGlobalpath() {  
  183.         return Environment.getExternalStorageDirectory().getAbsolutePath()  
  184.                 + File.separator + "crash" + File.separator;  
  185.     }  
  186.       
  187.     public static void setTag(String tag) {  
  188.         TAG = tag;  
  189.     }  
  190.       
  191.     /**
  192.      * 文件删除
  193.      * @param day 文件保存天数
  194.      */  
  195.     public void autoClear(final int autoClearDay) {  

  196.          
  197.     }  
  198.   
  199. }
复制代码
2.在Appcation中初始化

CrashHandler.getInstance().init(this);  

3.添加权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

4.查看效果






5.使用场景
发布出去的app运行崩溃时候上传错误信息,方便查找问题原因。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|不学网

GMT+8, 2018-9-26 18:20

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表