«

Android程序崩溃统一处理机制

时间:2024-3-2 18:35     作者:韩俊     分类: Android


在应用发布以后,由于安卓机型的千差万别 ,可能会出现各种各样的问题,这时候如果我们可以将这些信息收集起来,并进行修改就很不错了。下面就来讨论一下怎么处理程序崩溃以后,错误信息的手机。

Java中已经提供了一个接口Thread.UncaughtExceptionHandler来对运行时的异常进行处理。只需要实现这个接口,并覆写 public void uncaughtException(Thread thread, Throwable ex) 方法即可。

由于Application是Android应用启动的第一个入口,所以我们实现自己的Application,让他去实现Thread.UncaughtExceptionHandler接口。使用的时候有一下几个注意事项

1. 需要在manifest文件中的application节点,添加你自己实现的Application类,例如

 <application
        android:name=".CrashApplication"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

2.在实现的Application类的onCreate方法中,设置本类为默认的异常处理器,添加如下代码:

Thread.setDefaultUncaughtExceptionHandler(this);
     3.在uncaughtException(Thread thread, Throwable ex) 方法中添加实现。


示例代码如下,实现了收集发生异常的手机设备信息和异常信息,并将这些信息保存至本地

public class CrashApplication extends Application implements UncaughtExceptionHandler {

    // 单例模式
    private static CrashApplication INSTANCE;

    private Context mContext;
    // 用来存储设备信息和异常信息
    private Map<String, String> info = new HashMap<String, String>();
    // 用于格式化日期,作为日志文件名的一部分
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    public CrashApplication() {
    }

    public static CrashApplication getInstance() {

        if (INSTANCE == null) {
            INSTANCE = new CrashApplication();
        }
        return INSTANCE;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;

        // 设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    public void uncaughtException(Thread thread, Throwable ex) {
        // TODO,在这里你可以处理当 程序崩溃时你想做的事情

        // 收集设备参数信息
        collectDeviceInfo(mContext);
        // 保存日志文件
        saveCrashInfo2File(ex);
    }

    /**
     * 收集设备参数信息
     * 
     */
    public void collectDeviceInfo(Context context) {
        try {
            PackageManager pm = context.getPackageManager();// 获得包管理器
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);// 得到该应用的信息,即主Activity
            if (pi != null) {
                String versionName = pi.versionName == null ? "null" : pi.versionName;
                String versionCode = pi.versionCode + "";
                info.put("versionName", versionName);
                info.put("versionCode", versionCode);
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }

        Field[] fields = Build.class.getDeclaredFields();// 反射机制
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                info.put(field.getName(), field.get("").toString());
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 将异常信息保存至SD卡crash目录
     */
    private String saveCrashInfo2File(Throwable ex) {
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : info.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key + "=" + value + "rn");
        }
        Writer writer = new StringWriter();
        PrintWriter pw = new PrintWriter(writer);
        ex.printStackTrace(pw);
        Throwable cause = ex.getCause();
        // 循环着把所有的异常信息写入writer中
        while (cause != null) {
            cause.printStackTrace(pw);
            cause = cause.getCause();
        }
        pw.close();// 记得关闭
        String result = writer.toString();
        sb.append(result);
        // 保存文件
        long timetamp = System.currentTimeMillis();
        String time = format.format(new Date());
        String fileName = "crash-" + time + "-" + timetamp + ".log";
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            try {
                File dir = new File(Environment.getExternalStorageDirectory(), "crash");
                if (!dir.exists())
                    dir.mkdir();

                File file = new File(dir, fileName);

                FileOutputStream fos = new FileOutputStream(file);
                fos.write(sb.toString().getBytes());
                fos.close();
                return fileName;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}



标签: android

热门推荐