此功能的意义:
android应用很多时候有异常崩溃,导致用户体验很不好,而且开发者无法捕获到相关错误信息,也无法知悉。所以将主线程的崩溃信息,已邮件的形式或者
由GA统计事件上传给开发者,这是很有必要的。
实现思路:
java中线程Thread对象有方法setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler exceptionHandler),当线程发生运行时异常而中断时,ExceptionHandler对象就能捕捉到该信息。需要单独处理此异常,需要重写该类的public void uncaughtException(Thread arg0, Throwable arg1) 方法。
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
public void uncaughtException(Thread arg0, Throwable arg1) {
System.out.println("======"+arg1);
}
}
public void uncaughtException(Thread arg0, Throwable arg1) {
System.out.println("======"+arg1);
}
}
在android应用中应用:
众所周知,android主线程也是一个线程,那我们也可以给它添加ExceptionHandler,具体操作我们在application oncreate的时候初始化我们自己定义好的ExceptionHandler对象,然后设置给主线程。下面是具体实现类的例子。
public class CrashHandler implements UncaughtExceptionHandler {
/** Debug Log tag */
public static final String TAG = "CrashHandler";
/**
* 是否开启日志输出,在Debug状态下开启, 在Release状态下关闭以提示程序性能
* */
/** 系统默认的UncaughtException处理类 */
private Thread.UncaughtExceptionHandler mDefaultHandler;
/** CrashHandler实例 */
private static CrashHandler INSTANCE;
/** 程序的Context对象 */
private Context mContext;
/** 保证只有一个CrashHandler实例 */
private CrashHandler() {
}
/** 获取CrashHandler实例 ,单例模式 */
public static CrashHandler getInstance() {
if (INSTANCE == null) {
INSTANCE = new CrashHandler();
}
return INSTANCE;
}
/**
* 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
*
* @param ctx
*/
public void init(Context ctx) {
mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
AVLog.d(TAG, "catch uncaughtException:" + ex);
ex.printStackTrace();
if (!handleException(ex) && mDefaultHandler != null) {
AVLog.d(TAG, "user didn't handle exception");
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
AVLog.d(TAG, "uncaughtException kill process");
// Sleep一会后结束程序
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
AVLog.e(TAG, "Error : "+e);
}
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
String result = getStringFromThrowable(ex);
// 在此你可以将result数据上传ga或者由邮件发送或者写sdcard然后上传服务器。
return false;
}
// 从Throwable中获取异常信息
private String getStringFromThrowable(Throwable ex) {
Writer info = new StringWriter();
PrintWriter printWriter = new PrintWriter(info);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
String result = info.toString();
printWriter.close();
return result;
}
Writer info = new StringWriter();
PrintWriter printWriter = new PrintWriter(info);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
String result = info.toString();
printWriter.close();
return result;
}
}
在application oncreate方法中调用:
CrashHandler crashHandler = CrashHandler.getInstance();
// 注册crashHandler
crashHandler.init(getApplicationContext());
// 注册crashHandler
crashHandler.init(getApplicationContext());
ok,此功能介绍完成。