当app发布到市场,用户下载使用过程中如果出现crash的情况,对用户来说是非常不友好,有可能用户直接把应用给卸载了。因此捕获以及分析crash对我们来说至关重要,让我们及时修复异常,减少用户流失。
定义crash处理类CrashHandler,并且实现Thread.UncaughtExceptionHandler接口
public class CrashHandler implements Thread.UncaughtExceptionHandler { private final String PATH = "error"; private Context mContext; private Thread.UncaughtExceptionHandler mUncaughtExceptionHandler; public void init(Context context) { // 获取程序默认的异常处理 mUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); // 把自定义的异常处理替换默认的 Thread.setDefaultUncaughtExceptionHandler(this); mContext = context; } @Override public void uncaughtException(Thread thread, Throwable ex) { //获取异常写入文件 handleException(ex); //先判断是否链接了网络,开启后台服务,将异常文件上传到服务器 if(NetWorkState.IsConnectNet(mContext)) { Intent it = new Intent(mContext, ExceptionService.class); mContext.startService(it); } //如果系统提供了默认到异常处理,则交给系统去结束程序,否则自己结束 if(mUncaughtExceptionHandler != null) { mUncaughtExceptionHandler.uncaughtException(thread, ex); }else{ Process.killProcess(Process.myPid()); } } private boolean handleException(Throwable ex) { String xml = getExceptionXML(mContext, ex); if(xml != null) { //保存crash日志文件到sdcard String filename = SaveFile(xml.getBytes()); if(filename != null) { return true; } } return false; } public static String getExceptionXML(Context context, Throwable ex) { String xml = null; if(context != null && ex != null) { xml = ""; xml += collectDeviceInfo(context);//收集设备信息 xml += collectErrorInfo(ex); //收集错误信息 xml += " "; } return xml; } }复制代码
这里首先要获取得到crash信息,然后将crash信息存到sdcard,得到crash信息文件后,开启后台服务,将文件上传到后台即可。这里收集到信息包括:应用版本号、手机配置信息和crash信息。
public class ExceptionService extends Service { private boolean mIsRun; private Handler mHandler = new Handler(); @Override public void onCreate() { super.onCreate(); mIsRun = false; } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent != null && !mIsRun) { mIsRun = true; StartUpload(); } return super.onStartCommand(intent, flags, startId); } private void StartUpload() { new Thread(new Runnable() { @Override public void run() { //这里将crash文件上传到服务器 //上传文件完毕之后,关闭后台服务 mHandler.post(new Runnable() { @Override public void run() { ExceptionService.this.stopSelf(); System.exit(0); } }); } }).start(); }}复制代码
这个后台服务主要的工作就是将crash上传到服务器,上传完成就关闭服务。
public class BaseApplication extends Application { private static Context mContext; private CrashHandler mCrashHandler; @Override public void onCreate() { mContext = this; mCrashHandler = new CrashHandler(); mCrashHandler.init(mContext); super.onCreate(); } @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); } /** * 获取上下文 * * @return */ public static Context getContext() { return mContext; } public static BaseApplication getInstance() { return (BaseApplication) mContext; }}复制代码
这里需要在onCreate方法里面初始化CrashHandler,主要是为应用设置异常处理,然后程序才能获取未处理的异常。
经过上面的步骤就可以处理crash了,只要应用crash了就会将信息上传到服务器,我们从服务器中获取信息,分析crash进而处理这些bug。