程序崩溃是最让人头疼的事情。当用户使用时,如果是第一次运行就崩溃,那此程序一定没戏了。即使是偶尔崩溃也会让用户心里很不爽。其实这不能全怪我们程序员。有些问题,我们也无法预知啊。但,作为一名优秀的程序员,我们还是拦过责任来,就是我们的问题。我处理就是了。
处理思路:捕捉崩溃异常,重启并报告异常。
那么现在就面临三个问题。一个是怎样捕捉Uncaught Exception,一个是重启并报告异常。
问题一,捕捉Uncaught Exception
对于此问题,其实Java早就为我们做好了。Android系统沿用了Java的处理机制。既然如此,我们拿来用就成了。Java里有一个UncaughtExceptionHandler的接口,接口里有一个uncaughtException()的方法。还有一个类叫ThreadGroup extends UncaughtExceptionHandler。所以我们有两种方法去捕捉Uncaught Exception了。一种是extends ThreadGroup类并Override uncaughtException()方法;一种是implements UncaughtExceptionHandler接口并Override uncaughtException()方法。代码请往下看。
问题二,重启并报告异常
重启程序呢,有很多种方法,但归根结底就是两种,一种是通过Intent直接打开,一种是通过AlarmManager来定时启动。 代码请往下看。
报告异常其实也就是得到String信息进行处理。代码往下看。
不要忘记要退出程序,怎么退出呢:System.exit(0);android.os.Process.killProcess(android.os.Process.myPid());还有通过ActivityManager来实现。其实在高版本android系统中这些方法都没用了,google把这些都给废弃限制了。不过对本文要讲的问题没有什么影响。本文中要加入System.exit(0);或android.os.Process.killProcess(android.os.Process.myPid);。ActivityManager这种是不可行的。已测试。
实例代码
AppContext.java
package com.study.exceptionhandler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
/**
* @time 2015-09-19
* @author Leo
* @describe 应用管理和异常处理
*
*/
public class AppContext extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(mExceptionHandler);// 设置默认异常处理类
}
@Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
// insert handle code here
}
/**
* 自定义崩溃异常处理对象
*/
private UncaughtExceptionHandler mExceptionHandler = new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread arg0, Throwable arg1) {
// TODO Auto-generated method stub
restartApplication1();
System.exit(0);// 退出上次的程序 可以不加
android.os.Process.killProcess(android.os.Process.myPid());
}
};
/**
* 重启程序 程序不退出 但会闪屏
*/
private void restartApplication1() {
Intent intent = getPackageManager().getLaunchIntentForPackage(
getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
/**
* 重启程序 程序不退出 但会闪屏
*/
private void restartApplication2() {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
/**
* 通过定时器重启程序 程序会退出再打开
*/
private void restartApplication3() {
Intent intent = getPackageManager().getLaunchIntentForPackage(
getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent operation = PendingIntent.getActivity(
getApplicationContext(), 0, intent,
Intent.FLAG_ACTIVITY_NEW_TASK);
AlarmManager mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis(),
operation);
}
/**
* 错误信息 你可以保存到文件里 也可上传到服务器 想怎么处理就怎么处理
* @param ex
* @return
*/
private String getErrorInfo(Throwable ex) {
String info = null;
ByteArrayOutputStream baos = null;
PrintStream err = null;
try {
baos = new ByteArrayOutputStream();
err = new PrintStream(baos);
ex.printStackTrace(err);
byte[] bytes = baos.toByteArray();
info = new String(bytes);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (err != null)
err.close();
try {
if (baos != null)
baos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return info;
}
}
总结
Bug是解决不完的,但还是要解决的。不要问为什么,努力解决就是了。这样技术慢慢就提高了,离大神越来越进了。加油。