在程序开发中,经常会遇到各种各样的crash,一般只要找到crash的原因,那么就可以修复了,但是在实际开发中,程序员无法直接从用户手机上得到这些crash信息,这是就需要对这些异常信息进行处理,然后上传到服务器当中,供程序员进行调试、改进。
在Android中,有一个UncaughtExceptionHandler的接口,当crash发生的时候,系统就会自动的调用UncaughtExceptionHandler中的uncaughtException方法,我们可以再uncaughtException方法中进行处理,将异常信息写到SD卡当中去,然后在将Log文件上传到服务器中去。
①自定义一个CrashHandler类实现UncaughtExceptionHandler接口,并实现当中的方法:
<pre name="code" class="java">public class CrashHandler implements UncaughtExceptionHandler {②判断SD卡状态,将异常信息写入到SD卡当中,dumpPhoneInfo中将手机的基本信息也写入到SDK当中,方便我们调试。
@Override
public void uncaughtException(Thread thread, Throwable ex) {
}
}
public void dumpExceptionToSDCard(Throwable ex) throws IOException{
//SD卡不存在或无法使用,就无法把信息正常写入SD卡
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
if (Constant.DEBUG){
MyLog.w(TAG, "sdcard unmounted,skip dump exception");
return;
}
File dir = new File(PATH);
if (!dir.exists()){
dir.mkdirs();
}
long current = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date(current));
File file = new File(PATH+FILE_NAME+time+FILE_NAME_SUFFIX);
MyLog.e(TAG, file.getPath());
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
pw.println(time);
dumpPhoneInfo(pw);
pw.println();
ex.printStackTrace(pw);
pw.close();
}else {
MyLog.w(TAG, "sdcard has not found");
}
}
<pre name="code" class="html">private void dumpPhoneInfo(PrintWriter pw) {
PackageManager pm = mContext.getPackageManager();
PackageInfo pi = null;
try {
pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
} catch (NameNotFoundException e) {
MyLog.e(TAG, "dump crash info failed2");
}
pw.print("App Version:");
pw.print(pi.versionName);
pw.print('_');
pw.println(pi.versionCode);
//Android版本号
pw.print("OS Version:");
pw.print(Build.VERSION.RELEASE);
pw.print('_');
pw.println(Build.VERSION.SDK_INT);
//手机制造商
pw.print("Vendor:");
pw.println(Build.MANUFACTURER);
//手机型号
pw.print("Model:");
pw.println(Build.MODEL);
//CPU架构
pw.print("CPU ABI:");
pw.println(Build.CPU_ABI);
}
③将Crash信息上传到服务器中,这里根据自己的服务器自己完成
//将Crash文件上传到服务器下面自己写一个RunTimeException测试一下我们写的是否正确,点击一个按钮,跑出一个异常
@SuppressWarnings("unused")
private void uploadExceptionToServer(){
}
btn_crash.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {throw new RuntimeException("自定义异常:这是自己抛出的异常");}});
程序崩溃,我们在自定义的目录下找一个我们保存的crash信息文件
当我们看到上述信息后,调试程序也就游刃有余啦。
为了在程序退出时更人性化一些,我们最好不要采用系统自带的强制退出,我们,在捕捉到异常并保存后,弹出toast,友好的告诉用户系统即将退出。
@Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
dumpExceptionToSDCard(ex);
uploadExceptionToServer();
} catch (IOException e) {
e.printStackTrace();
}
ex.printStackTrace();
showToast(mContext, "程序运行异常,正在关闭");
try {
thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
myApplication.exit();
//if (mDefaultCrashHandler!=null){
//mDefaultCrashHandler.uncaughtException(thread, ex);
//}else{
//android.os.Process.killProcess(android.os.Process.myPid());
//}
}
完整代码连接
http://download.csdn.net/detail/itydxtocattle/9322099