惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
B
Blog
博客园_首页
云风的 BLOG
云风的 BLOG
S
SegmentFault 最新的问题
罗磊的独立博客
Jina AI
Jina AI
C
Check Point Blog
Martin Fowler
Martin Fowler
J
Java Code Geeks
博客园 - 司徒正美
美团技术团队
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
有赞技术团队
有赞技术团队
U
Unit 42
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
小众软件
小众软件

博客园 - Class Xman

手动建库时一个小错误:ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance Windows下USB磁盘开发系列二:枚举系统中所有USB设备 Clouda聊天室实践 ASP.NET Repeater嵌套Repeater实现菜单加载 浅说正则——会了就不会忘 android开发中难免遇到listview刷新数据出现异常 hdu2068RPG的错排 用实例讲解RSA加密算法(精) ARM——操作系统—最小操作系统-开发板测试 HTML入门教程 HDU 4770 Lights Against DudelyLights (顺序表的应用5.4.3)POJ 1012(约瑟夫环问题——保证前k个出队元素为后k个元素) IE7 float:left失效的解决方法 android实现通过浏览器点击链接打开本地应用(APP)并拿到浏览器传递的数据 如何避免来自企业内部的网络安全威胁(二) Android安装失败 Installation error code: -110 Android TextWatcher监控EditText中的输入内容并限制其输入字符个数 不让自己的应用程序在桌面的图标列表里启动显示的方法 Fragment与FragmentAcitvity间的传值
Android 程序崩溃后的处理
Class Xman · 2013-11-14 · via 博客园 - Class Xman

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

       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;
	}
}