在Java 的异常处理机制中:1如果抛出的是Exception异常的话,必须有try..catch..进行处理,属于checked exception。2如果抛出的是RuntimeException异常的话,则不是必须进行try..catch..异常处理,发生异常之后将由JVM进行处理,属于unchecked exception。
在Android开发中,常常会出现uncheched Exception 导致程序的crash,为了提供良好的用户体验,并对出错的信息进行收集,以便对程序进行改进,提高程序的健壮性。因此,常使用Thread.UncaughtExceptionHandler来进行处理。
/**
*@authorzhouyan0 UncaughtException处理类,当程序发生Uncaught异常的时候,有该类 来接管程序,并记录
* 发送错误报告.. 註冊方式 CaptureCrashException crash =
* CaptureCrashException.getInstance(); //注册crashHandler
* crash.init(getApplicationContext()); //初始化
* crash.sendPreviousReportsToServer();//发送以前没发送的报告(可选)
*
*/
public class CaptureCrashException implements UncaughtExceptionHandler {
/** 系统默认的UncaughtException处理类 */
private UncaughtExceptionHandler mDefaultHandler;
/** CaptureCrashException实例 */
private static CaptureCrashException instance;
/** 程序的Context对象 */
private Context mContext;
/** 使用Properties来保存设备的信息和错误堆栈信息 */
private static final String VERSION_NAME="versionName";
private static final String VERSION_CODE="versionCode";
/** 保证只有一个CaptureCrashException实例 */
private CaptureCrashException() {
}
/** 获取CrashHandler实例 ,单例模式 */
public static CaptureCrashException getInstance() {
if(instance==null) {
instance=new CaptureCrashException();
}
returninstance;
}
/*** 初始化,注册Context对象, 获取系统默认的UncaughtException处理器,
* 设置该CaptureCrashException为程序的默认处理器*/
public voidinit(Context ctx) {
mContext= ctx;
mDefaultHandler= Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public voiduncaughtException(Thread thread, Throwable ex) {
if(!handleException(ex) &&mDefaultHandler!=null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
}else{
newThread() {
@Override
public voidrun() {
SystemClock.sleep(2000);
MyApplication.getInstance().removeAll();
}
}.start();
}
}
/*** 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑*@returntrue:如果处理了该异常信息;否则返回false*/
private boolean handleException(Throwable ex) {
if(ex ==null) {
return true;
}
// 输出到日志
StringWriter sw =newStringWriter();
PrintWriter pw =newPrintWriter(sw);
ex.printStackTrace(pw);
MyLogger.systemlLog().e(sw.toString());
// // 保存异常日志到sd卡
// saveErrorLog(ex);
//
// // 收集设备信息
// saveDeviceInfo();
//Log.e("-------------bug",ex.toString());
// 发送异常信息到服务器
//bugly 手动上报
CrashReport.postCatchedException(ex);
//Log.e("-------------bug","上传成功");
new Thread() {
@Override
public voidrun() {
Looper.prepare();
ToolAlert.showCustomShortToast("程序崩溃了, 重新打开试试!");
Looper.loop();
}
}.start();
return true;
}
/**
* 保存异常日志
*
*@paramex
*/
public voidsaveErrorLog(Throwable ex) {
String errorlog ="";
String savePath ="";
String logFilePath ="";
FileWriter fw =null;
PrintWriter pw =null;
try{
// 判断是否挂载了SD卡
String storageState = Environment.getExternalStorageState();
if(storageState.equals(Environment.MEDIA_MOUNTED)) {
savePath = ConstantManager.logPath;
File file =newFile(savePath);
if(!file.exists()) {
file.mkdirs();
}
errorlog ="errorlog "
+ ToolDateTime.getdateTime()
+".txt";
logFilePath = savePath + errorlog;
}
// 没有挂载SD卡, 无法写文件
if(logFilePath =="") {
return;
}
File logFile =newFile(logFilePath);
if(!logFile.exists()) {
logFile.createNewFile();
}
fw =newFileWriter(logFile,true);
pw =newPrintWriter(fw);
ex.printStackTrace(pw);
pw.close();
fw.close();
}catch(Exception e) {
e.printStackTrace();
}finally{
if(pw !=null) {
pw.close();
}
if(fw !=null) {
try{
fw.close();
}catch(IOException e) {
}
}
}
}
/**
* 保存设备信息
*
*@param
*/
public voidsaveDeviceInfo() {
String errorlog ="";
String savePath ="";
String logFilePath ="";
FileWriter fw =null;
PrintWriter pw =null;
try{
// 判断是否挂载了SD卡
String storageState = Environment.getExternalStorageState();
if(storageState.equals(Environment.MEDIA_MOUNTED)) {
savePath = ConstantManager.logPath;
File file =newFile(savePath);
if(!file.exists()) {
file.mkdirs();
}
errorlog ="deviceInfo "
+ ToolDateTime.getdateTime()
+".txt";
logFilePath = savePath + errorlog;
}
// 没有挂载SD卡, 无法写文件
if(logFilePath =="") {
return;
}
File logFile =newFile(logFilePath);
if(!logFile.exists()) {
logFile.createNewFile();
}
fw =newFileWriter(logFile,true);
pw =newPrintWriter(fw);
// 版本号
PackageManager pm =mContext.getPackageManager();
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),
PackageManager.GET_ACTIVITIES);
if(pi !=null) {
pw.println(VERSION_NAME+"="+ pi.versionName==null?"not set"
: pi.versionName);
pw.println(VERSION_CODE+"="+ pi.versionCode);
}
// 使用反射来收集设备信息.在Build类中包含各种设备信息,
// 例如: 系统版本号,设备生产商 等帮助调试程序的有用信息
Field[] fields = Build.class.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
pw.println(field.getName() +"="+ field.get(null));
}
pw.close();
fw.close();
}catch(Exception e) {
e.printStackTrace();
}finally{
if(pw !=null) {
pw.close();
}
if(fw !=null) {
try{
fw.close();
}catch(IOException e) {
}
}
}
}
/**
* 清空错误日志缓存目录
*/
public voidclearSavePathFile() {
File file =newFile(ConstantManager.logPath);
ToolFile.deleteFileOrDir(file);
}
}
在第一个actvity onCreate()中调用
// 开启线程, 进行初始化操作
new Thread() {
@Override
public void run() {
// 初始化CaptureCrashException
CaptureCrashException.getInstance().init(MyApplication.getMyApplication());
MyLogger.systemlLog().i("初始化完成");
}
}.start();
网友评论