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(); }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。