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

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 + "\r\n");
}
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 程序崩溃后的处理的更多相关文章

  1. android程序崩溃后重启

    有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动 应用这个问题困恼了我很久,今天终于解决了该问 ...

  2. 捕android程序崩溃日志

    主要类别: package com.example.callstatus; import java.io.File; import java.io.FileOutputStream; import j ...

  3. android 程序崩溃crash日志的捕捉

    android 程序崩溃crash日志的捕捉 之前在项目开发过程中,一直会遇到程序崩溃了,但是测试組的哥哥们又没及时的导出日志.... 后来在诳群的时候听别人说起,腾讯有那么一个叫bugly的东西 将 ...

  4. 结合程序崩溃后的core文件分析bug

    引言     在<I/O的效率比较>中,我们在修改图1程序的BUF_SIZE为8388608时,运行程序出现崩溃,如下图1:          图1. 段错误     一般而言,导致程序段 ...

  5. Android程序崩溃异常收集框架

    最近在写Android程序崩溃异常处理,完成之后,稍加封装与大家分享. 我的思路是这样的,在程序崩溃之后,将异常信息保存到一个日志文件中,然后对该文件进行处理,比如发送到邮箱,或发送到服务器. 所以, ...

  6. android双进程守护,让程序崩溃后一定可以重启

    由于我们做的是机器人上的软件,而机器人是24小时不间断服务的,这就要求我们的软件不能退出到系统桌面.当然最好是能够做到程序能够不卡顿,不崩溃,自己不退出.由于我们引用了很多第三方的开发包,也不能保证他 ...

  7. Android应用崩溃后异常捕获并重启并写入日志

    在Android开发时,有时会因为一些异常导致应用报错,偶尔会因为错误 而崩溃,导致用户体验下降,为了解决这问题,我们就要对这样的异常处理: 代码如下: CrashHandler.java impor ...

  8. Android程序安装后在模拟器上不显示,并且控制台显示The launch will only sync the application package on the device!

    初学安卓,今天写了一个小例子,可是eclipse控制台却提示 No Launcher activity found! The launch will only sync the application ...

  9. Android 程序崩溃之后fragment出现画面重叠问题

    1.解决方法: 直接在包含Fragment的Activity中复写onSaveInstanceState()方法,使其空实现 @Override protected void onSaveInstan ...

随机推荐

  1. 遍历Map的两种方法(有排序)

    初始化一个map Map<String, String> map = new HashMap<String, String>(); map.put("1", ...

  2. [zt]java synchronized详解

    作者:GangWang 出处:http://www.cnblogs.com/GnagWang/ 记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多 ...

  3. php继承后构造函数的特性

    在5.x版本的php中: 如果父类有构造函数,它的子类也有构造函数,那么在运行子类时就“不会执行父类的构造函数”. 要想执行父类的构造函数,需要在子类的构造函数中加上: parent::__const ...

  4. toLowerCase和toLocaleLowerCase的区别

    ECMAScript中涉及字符串大小写转换的方法有4个:toLowerCase().toLocaleLowerCase().toUpperCase()和toLocaleUpperCase().其中,t ...

  5. spring security 匿名登录

    匿名登录,即用户尚未登录系统,系统会为所有未登录的用户分配一个匿名用户,这个用户也拥有自己的权限,不过他是不能访问任何被保护资源的. 设置一个匿名用户的好处是,我们在进行权限判断时,可以保证Secur ...

  6. html 前端 总结(一)

    前端 html 总结(一) 基础部分:计算机原理 a: 是由运算器 控制器 内存组成储存器包括内存.外村外存 硬盘内存 由外村调入到内存执行输入——内存——cpu 运算 cpu运算——内存——输出设备 ...

  7. mysql语句中有引号的问题解决方案

    在mysql的查询.修改.插入.删除的sql语句里有引号如何处理? 例如: <? $name = "my name is xcxc"; $people = "i'm ...

  8. 为Eclipse安装主题插件

    方法2:通过站点更新 eclipse:Help->Install New Software->Work with:Update Site -http://eclipse-color-the ...

  9. ThinkPHP 3.2.3 Widget 扩展的使用

    ThinkPHP3.2.3 手册中 Widget 扩展的地址是: http://www.kancloud.cn/manual/thinkphp/1862 Widget 扩展一般用于页面组件的扩展,和自 ...

  10. php mysql_num_rows() 与 mysql_affected_rows()

    mysql_num_rows(data) 函数返回结果集中行的数目. data 结果集.该结果集从 mysql_query() 的调用中得到. 此命令仅对 SELECT 语句有效.要取得被 INSER ...