当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 version=\"1.0\" encoding=\"utf-8\" ?><info>";
xml += collectDeviceInfo(context);//收集设备信息
xml += collectErrorInfo(ex); //收集错误信息
xml += "</info>";
}
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。