Android实现自定义Crash handler记录崩溃信息实例代码
前言
在使用自己开发的android应用时,偶尔会出现系统已停止运行错误.这时候如果能记录错误日志,是非常有帮助的。
App异常崩溃信息存入文件中。
应用崩溃时,尽可能的收集多的数据,方便后续定位追踪修改。
如果可以,尽量将崩溃日志上传到服务器。一些集成服务已经提供了相应的功能。
主要使用的方法是Thread.UncaughtExceptionHandler
方法如下
一般在application中启动CrashHandler,个人认为应该放在调用其他模块前尽早启动。
CrashHandler.java
importandroid.os.Build;
importandroid.os.Environment;
importandroid.os.Process;
importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.PrintWriter;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Locale;
publicclassCrashHandlerimplementsThread.UncaughtExceptionHandler{
privatestaticfinalStringTAG="CrashHandler";
privatestaticfinalbooleanDEBUG=true;
//自定义存储的目录
privatestaticfinalStringPATH=Environment.getExternalStorageDirectory().getPath()+"/myApp/log/";
privatestaticfinalStringFILE_NAME="crash";
privatestaticfinalStringFILE_NAME_SUFFIX=".txt";
privateStringphoneInfo;
privatestaticCrashHandlerinstance=newCrashHandler();
privateThread.UncaughtExceptionHandlermDefaultCrashHandler;
privateCrashHandler(){
}
publicstaticCrashHandlergetInstance(){
returninstance;
}
publicvoidinit(){
mDefaultCrashHandler=Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
phoneInfo=getPhoneInformation();
}
/**
*这个是最关键的函数,当程序中有未被捕获的异常,系统将会自动调用uncaughtException方法
*thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex,我们就可以得到异常信息
*/
@Override
publicvoiduncaughtException(Threadthread,Throwableex){
try{
//导出异常信息到SD卡中
dumpExceptionToSDCard(ex);
//这里可以上传异常信息到服务器,便于开发人员分析日志从而解决bug
uploadExceptionToServer();
}catch(IOExceptione){
e.printStackTrace();
}
ex.printStackTrace();
//如果系统提供默认的异常处理器,则交给系统去结束程序,否则就由自己结束自己
if(mDefaultCrashHandler!=null){
mDefaultCrashHandler.uncaughtException(thread,ex);
}else{
try{
Thread.sleep(2000);//延迟2秒杀进程
}catch(InterruptedExceptione){
e.printStackTrace();
}
android.os.Process.killProcess(Process.myPid());
}
}
privatevoiddumpExceptionToSDCard(Throwableex)throwsIOException{
//如果SD卡不存在或无法使用,则无法把异常信息写入SD卡
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
if(DEBUG){
Log.e(TAG,"sdcardunmounted,skipdumpexception");
return;
}
}
Filedir=newFile(PATH);
if(!dir.exists()){
dir.mkdirs();
}
longcurrent=System.currentTimeMillis();
Stringtime=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss",Locale.CHINA).format(newDate(current));
Filefile=newFile(PATH+FILE_NAME+time+FILE_NAME_SUFFIX);
try{
PrintWriterpw=newPrintWriter(newBufferedWriter(newFileWriter(file)));
pw.println(time);
pw.println(phoneInfo);
pw.println();
ex.printStackTrace(pw);
pw.close();
Log.e(TAG,"dumpcrashinfoseccess");
}catch(Exceptione){
Log.e(TAG,e.getMessage());
Log.e(TAG,"dumpcrashinfofailed");
}
}
privatevoiduploadExceptionToServer(){
//将异常信息发送到服务器
}
privateStringgetPhoneInformation(){
StringBuildersb=newStringBuilder();
sb.append("Appversionname:")
.append(BuildConfig.VERSION_NAME)
.append(",versioncode:")
.append(BuildConfig.VERSION_CODE).append("\n");
//Android版本号
sb.append("OSVersion:");
sb.append(Build.VERSION.RELEASE);
sb.append("_");
sb.append(Build.VERSION.SDK_INT).append("\n");
//手机制造商
sb.append("Vendor:");
sb.append(Build.MANUFACTURER).append("\n");
//手机型号
sb.append("Model:");
sb.append(Build.MODEL).append("\n");
//CPU架构
sb.append("CPUABI:").append("\n");
for(Stringabi:Build.SUPPORTED_ABIS){
sb.append(abi).append("\n");
}
returnsb.toString();
}
}
使用方式,可在Application中调用初始化方法
@Override
publicvoidonCreate(){
super.onCreate();
//initapplication...
CrashHandler.getInstance().init();
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。