乐乐音乐播放器(五) 全局异常捕捉

源码下载“:http://www.eoeandroid.com/thread-587310-1-1.html

当我们的应用在出现bug并强制退出的时候,我们可能不捕捉不了相关的异常,不过,我们可以设置自定义的异常来捕捉全局异常
1.捕捉全局异常的类

  1. package com.happy.application;

  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.PrintWriter;
  5. import java.io.StringWriter;
  6. import java.io.Writer;
  7. import java.lang.Thread.UncaughtExceptionHandler;
  8. import java.lang.reflect.Field;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. import java.util.HashMap;
  12. import java.util.Map;

  13. import android.app.Application;
  14. import android.content.Context;
  15. import android.content.pm.PackageInfo;
  16. import android.content.pm.PackageManager;
  17. import android.content.pm.PackageManager.NameNotFoundException;
  18. import android.os.Build;
  19. import android.os.Looper;
  20. import android.widget.Toast;

  21. import com.happy.common.Constants;
  22. import com.happy.logger.LoggerManage;

  23. public class CrashApplication extends Application {

  24.         @Override
  25.         public void onCreate() {
  26.                 super.onCreate();
  27.                 CrashHandler catchHandler = new CrashHandler();
  28.                 catchHandler.init(getApplicationContext());
  29.         }

  30.         /**
  31.          * UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误报告.
  32.          * 
  33.          * 需要在Application中注册,为了要在程序启动器就监控整个程序。
  34.          */
  35.         public class CrashHandler implements UncaughtExceptionHandler {

  36.                 private LoggerManage logger;
  37.                 private SimpleDateFormat crashfile = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式

  38.                 // 系统默认的UncaughtException处理类
  39.                 private Thread.UncaughtExceptionHandler mDefaultHandler;
  40.                 // 程序的Context对象
  41.                 private Context mContext;
  42.                 // 用来存储设备信息和异常信息
  43.                 private Map<String, String> infos = new HashMap<String, String>();

  44.                 /** 保证只有一个CrashHandler实例 */
  45.                 private CrashHandler() {
  46.                 }

  47.                 /**
  48.                  * 初始化
  49.                  */
  50.                 public void init(Context context) {
  51.                         mContext = context;
  52.                         logger = LoggerManage.getZhangLogger(mContext);
  53.                         // 获取系统默认的UncaughtException处理器
  54.                         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  55.                         // 设置该CrashHandler为程序的默认处理器
  56.                         Thread.setDefaultUncaughtExceptionHandler(this);
  57.                 }

  58.                 /**
  59.                  * 当UncaughtException发生时会转入该函数来处理
  60.                  */
  61.                 @Override
  62.                 public void uncaughtException(Thread thread, Throwable ex) {
  63.                         if (!handleException(ex) && mDefaultHandler != null) {
  64.                                 // 如果用户没有处理则让系统默认的异常处理器来处理
  65.                                 mDefaultHandler.uncaughtException(thread, ex);
  66.                         } else {
  67.                                 try {
  68.                                         Thread.sleep(1000);
  69.                                 } catch (InterruptedException e) {
  70.                                         logger.e(e.toString());
  71.                                 }
  72.                                 // 退出程序
  73.                                 android.os.Process.killProcess(android.os.Process.myPid());
  74.                                 System.exit(1);
  75.                         }
  76.                 }

  77.                 /**
  78.                  * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
  79.                  * 
  80.                  * @param ex
  81.                  * [url=home.php?mod=space&uid=7300]@return[/url] true:如果处理了该异常信息;否则返回false.
  82.                  */
  83.                 private boolean handleException(Throwable ex) {
  84.                         if (ex == null) {
  85.                                 return false;
  86.                         }
  87.                         // 收集设备参数信息
  88.                         collectDeviceInfo(mContext);
  89.                         // 使用Toast来显示异常信息
  90.                         new Thread() {
  91.                                 @Override
  92.                                 public void run() {
  93.                                         Looper.prepare();
  94.                                         Toast.makeText(mContext, "程序出现异常,即将退出", Toast.LENGTH_SHORT)
  95.                                                         .show();
  96.                                         Looper.loop();
  97.                                 }
  98.                         }.start();
  99.                         // 保存日志文件
  100.                         saveCatchInfoFile(ex);
  101.                         return true;
  102.                 }

  103.                 /**
  104.                  * 收集设备参数信息
  105.                  * 
  106.                  * @param mContext
  107.                  */
  108.                 private void collectDeviceInfo(Context ctx) {
  109.                         // 获取当前程序的版本号. 版本的id
  110.                         try {
  111.                                 PackageManager pm = ctx.getPackageManager();
  112.                                 PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
  113.                                                 PackageManager.GET_ACTIVITIES);
  114.                                 if (pi != null) {
  115.                                         String versionName = pi.versionName == null ? "null"
  116.                                                         : pi.versionName;
  117.                                         String versionCode = pi.versionCode + "";
  118.                                         infos.put("versionName", versionName);
  119.                                         infos.put("versionCode", versionCode);
  120.                                 }
  121.                         } catch (NameNotFoundException e) {
  122.                                 logger.e(e.toString());
  123.                         }
  124.                         // 获取手机的硬件信息
  125.                         // 通过反射获取系统的硬件信息
  126.                         Field[] fields = Build.class.getDeclaredFields();
  127.                         for (Field field : fields) {
  128.                                 try {
  129.                                         field.setAccessible(true);
  130.                                         infos.put(field.getName(), field.get(null).toString());
  131.                                 } catch (Exception e) {
  132.                                         logger.e(e.toString());
  133.                                 }
  134.                         }
  135.                 }

  136.                 /**
  137.                  * 保存日志文件
  138.                  * 
  139.                  * @param ex
  140.                  */
  141.                 private void saveCatchInfoFile(Throwable ex) {

  142.                         StringBuffer sb = new StringBuffer();
  143.                         for (Map.Entry<String, String> entry : infos.entrySet()) {
  144.                                 String key = entry.getKey();
  145.                                 String value = entry.getValue();
  146.                                 sb.append(key + "=" + value + "\n");
  147.                         }

  148.                         Writer writer = new StringWriter();
  149.                         PrintWriter printWriter = new PrintWriter(writer);
  150.                         ex.printStackTrace(printWriter);
  151.                         Throwable cause = ex.getCause();
  152.                         while (cause != null) {
  153.                                 cause.printStackTrace(printWriter);
  154.                                 cause = cause.getCause();
  155.                         }
  156.                         printWriter.close();
  157.                         String result = writer.toString();
  158.                         sb.append(result);
  159.                         try {
  160.                                 // 用于格式化日期,作为日志文件名的一部分
  161.                                 String time = crashfile.format(new Date());
  162.                                 String fileName = time + ".log";
  163.                                 String path = Constants.PATH_CRASH + File.separator;
  164.                                 File dir = new File(path);
  165.                                 if (!dir.exists()) {
  166.                                         dir.mkdirs();
  167.                                 }
  168.                                 FileOutputStream fos = new FileOutputStream(path + fileName);
  169.                                 fos.write(sb.toString().getBytes());
  170.                                 fos.close();
  171.                         } catch (Exception e) {
  172.                                 logger.e(e.toString());
  173.                         }
  174.                 }
  175.         }
  176. }
复制代码
2.在配置文件声明
<application
        android:name="com.happy.application.CrashApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"

3.调用
  1. package com.happy.ui;

  2. import com.happy.logger.LoggerManage;

  3. import android.os.Bundle;
  4. import android.app.Activity;
  5. import android.view.Menu;

  6. public class MainActivity extends Activity {

  7.         private LoggerManage logger;

  8.         @Override
  9.         protected void onCreate(Bundle savedInstanceState) {
  10.                 super.onCreate(savedInstanceState);
  11.                 setContentView(R.layout.activity_main);
  12.                 init();
  13.         }

  14.         private void init() {
  15. //                logger = LoggerManage.getZhangLogger(this);
  16.                 logger.i("测试");
  17.         }

  18.         // @Override
  19.         // public boolean onCreateOptionsMenu(Menu menu) {
  20.         // getMenuInflater().inflate(R.menu.main, menu);
  21.         // return true;
  22.         // }

  23. }
复制代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值