系统发生异常时会有一个类去捕获,
Thread.UncaughtExceptionHandler, 实现这个接口,重写捕获异常的函数,就可以对异常进行操作、
获取到app版本,在发生异常的是时候记录异常发生的时间,原因,可将这些异常保存到本地文件里边
(通过log4j等第三方框架);
可以将异常发到服务器上,貌似用友盟可以做这个操作;遇到异常可以重新启动app。
public class AppError implements Thread.UncaughtExceptionHandler {
private Context mContext;
public AppError(Context context) {//context传入application
this.mContext=context;
}
private static final String TAG = "AppError";
protected boolean isSendEmail = true;
//系统默认的UncaughtException处理类
protected Thread.UncaughtExceptionHandler mDefaultHandler;
/*初始化*/
public void initUncaught() {
//获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
/*当UncaughtException发生时会转入该函数来处理*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
//AppException.exc(e).makeToast(AppContext.getContext());
}
Log.d(TAG,"很抱歉,程序出现异常,会返回登录页面.");
/* AlarmManager mgr = (AlarmManager) mApp.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(mApp.getApplicationContext(), PrisonLoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("crash", true);
PendingIntent restartIntent = PendingIntent.getActivity(mApp.getApplicationContext(), 0, intent,
PendingIntent.FLAG_ONE_SHOT);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
*/
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
// Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
if (isSendEmail) {
sendErrorInfoMail(ex);
}
//保存日志文件
// saveErrorLog(ex);
return true;
}
public void sendErrorInfoMail(Throwable ex) {
StringBuffer sb = new StringBuffer();
sb.append("--------------" + (new Date().toLocaleString()) + ",version" + getVersion() + "---------------\n");
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
Log.e(TAG,sb.toString());
}
/**
* 保存异常日志
*/
public void saveErrorLog(Throwable ex) {
StringBuffer sb = new StringBuffer();
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
try {
ex.printStackTrace(printWriter);
} catch (Exception e) {
e.printStackTrace();
}
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
//在控制台打印
System.err.println(sb.toString());
String errorlog = "throwable_log" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".txt";
String savePath = "";
// String logFilePath = "";
File logDir = null;
FileWriter fw = null;
PrintWriter pw = null;
try {
//判断是否挂载了SD卡
String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
//Environment.getExternalStorageDirectory().getAbsolutePath()
savePath = mContext.getExternalCacheDir()+"" ;
logDir = new File(savePath);
if (!logDir.exists()) {
logDir.mkdirs();
}
}
//没有挂载SD卡,无法写文件
if (logDir == null || !logDir.exists() || !logDir.canWrite()) {
return;
}
File logFile = new File(logDir, errorlog);
if (!logFile.exists()) {
logFile.createNewFile();
}
fw = new FileWriter(logFile, true);
pw = new PrintWriter(fw);
pw.println("--------------" + (new Date().toLocaleString()) + ",version" + getVersion() + "---------------\n");
pw.write(sb.toString());
pw.close();
fw.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
}
}
}
}
/**
* 获取版本号
* @return 当前应用的版本号
*/
public String getVersion() {
try {
PackageManager manager = mContext.getPackageManager();
PackageInfo info = manager.getPackageInfo(mContext.getPackageName(), 0);
String version = info.versionName;
return version;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}