1- CrashHandler 知识点的使用
在Android
中我们经常遇到错误,根据不同的机型,不同的网络情况,在我们的产品上线之后, 用户在不同的环境中可能会产生不同的bug
,但是这些bug
是我们在上现在之前的测试环节没有测试出来的隐形bug
;而此时我们开发人员没有办法获取bug
的log
日志进行分析,就比较麻烦;此时我们就需要借助 CrashHandler
捕获全局异常并且进行处理,将日志发送我们的服务器了;
java
的Thread
中有一个UncaughtExceptionHandler
接口,该接口的作用主要是为 了 当 Thread
因未捕获的异常而突然终止时,调用处理程序。
接口下面有setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
方法,方法主要作用为设置当线程由于未捕获到异常而突然终止时,并且没有为该线程定义其他处理程序时所调用的默认处理程序。
所以我们可以这样设计一个CrashHandler:
1- 写一个CrashHandler类
,实现UncaughtExceptionHandler
这个接口
public class CrashHandler implements UncaughtExceptionHandler{}
2- 将这个自定义的CrashHandler类 设置到异常发生处理中去,此时异常发生则会调用自定义的处理中的方法
Thread.setDefaultUncaughtExceptionHandler(CrashHandler.getInstance);
3- 因为是全局异常 所以将CranshHandler
设置成单列模式,并且在APPlication
中调用
/** 获取CrashHandler实例 ,单例模式*/
public static CrashHandler getInstance() {
if (instance == null) {
instance = new CrashHandler();
}
return instance;
}
4- 实现最重要的 异常发生时候的回调方法 public void uncaughtException(Thread arg0, Throwable arg1){}
5- 进行保存 log
和上传后台
除此之外某些第三方也集成了该功能,如友盟提供了次集成sdk,可将bug直接发送到Umeng应用后台
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG = CrashHandler.class.getSimpleName();
private static CrashHandler mCrashHandler;
private CrashHandler(){
}
/**
* 单列模式 全局只有一个
* @return
*/
public static CrashHandler getInstance(){
if(mCrashHandler == null){
mCrashHandler = new CrashHandler();
}
return mCrashHandler;
}
public void init(){
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 核心方法,当程序出现crash的时候回调
* @param thread
* @param throwable
*/
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
Log.e(TAG, "uncaughtException: CrashHanlder捕获中..." );
String logName = "_log.txt";
File logFile = new File(Constant.Log_PATH);
if(!logFile.exists()){
logFile.mkdirs();
}
PrintWriter printWriter = null;
StringBuffer stringBuffer = new StringBuffer();
String device_model = Build.MODEL; // 设备型号
int version_sdk = Build.VERSION.SDK_INT; // 设备SDK版本
String version_release = Build.VERSION.RELEASE; // 设备的系统版本
try {
printWriter = new PrintWriter(new File(Constant.Log_PATH +File.separator + logName));
stringBuffer.append("log==》time: "+new Date())
.append("\n")
.append("device_model: ")
.append(device_model)
.append("\n")
.append("version_sdk: ")
.append(version_sdk)
.append("\n")
.append("version_release: ")
.append(version_release)
.append("\n")
.append(throwable.getMessage());
StackTraceElement[] stackTrace = throwable.getStackTrace();
for (StackTraceElement s : stackTrace) {
stringBuffer.append("file:").append(s.getFileName())
.append(" class:").append(s.getClassName())
.append(" method:").append(s.getMethodName())
.append(" line:").append(s.getLineNumber()).append("\n");
}
printWriter.println(stringBuffer.toString());
printWriter.close();
//上传到服务器
//......
} catch (FileNotFoundException e) {
e.printStackTrace();
}
throwable.printStackTrace();
//这里可以配置 崩溃之后跳转到开始页面之类的
android.os.Process.killProcess(Process.myPid());//杀死进程,关闭程序
}
}