前言:在开发安卓的过程中,debug绝对是任何开发人员极为痛绝的事情。在本地开发过程中,如果出现错误,还可以查看logcat信息,但是市场上的手机五花八门,各种型号各种屏幕尺寸,甚至各种各样的用户,开发者难以确定什么时候用户会出现bug.那么搜集已经发布的版本bug信息,对于版本更新和用户体验是十分重要的事情,那么如何实现?
在项目中用到这种需求,花了半天时间研究了一下,具体用法待我一一道来。
首先,是实现UncaughtExceptionHandler。
/**
* 收集用户手机崩溃信息,上传服务器
* Created by xygy on 2015/7/30.
*/
public class UserError implements Thread.UncaughtExceptionHandler{
private String TAG = "usererror-------->";
private Context context;
//获取系统的版本号
private int versionMain;//大的版本号,如1
private int versionMini;//小的版本号,如.1
//用于格式化日期,作为日志文件名的一部分
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
//实例
private static UserError userError;
//系统默认处理实例
private Thread.UncaughtExceptionHandler exceptionHandler;
//初始化
public void init(Context context){
this.context = context;
//获取默认实例
exceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 使用单例模式
* 构造函数设置为private
*/
private UserError(){}
public static UserError getInstance(){
if(userError == null){
return new UserError();
}else{
return userError;
}
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.v(TAG, "thread.getName()------------------------>" + thread.getName());
caughtException(thread, ex);
//调用系统默认处理
exceptionHandler.uncaughtException(thread, ex);
//如果不是主线程,则强制关闭线程
if(thread.getName().equals("main")){
Log.v(TAG, "usererror------------------------>" + null);
}else{
}
}
/**
* 处理用户的崩溃信息
* @param thread
* @param ex
*/
private void caughtException(Thread thread, Throwable ex){
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
//获取跟踪的栈信息,除了系统栈信息,还把手机型号、系统版本、编译版本的唯一标示上传
StackTraceElement[] trace = ex.getStackTrace();
StackTraceElement[] trace2 = new StackTraceElement[trace.length+3];
System.arraycopy(trace, 0, trace2, 0, trace.length);
trace2[trace.length+0] = new StackTraceElement("Android", "MODEL", android.os.Build.MODEL, -1);
trace2[trace.length+1] = new StackTraceElement("Android", "VERSION", android.os.Build.VERSION.RELEASE, -1);
trace2[trace.length+2] = new StackTraceElement("Android", "FINGERPRINT", android.os.Build.FINGERPRINT, -1);
//追加信息,因为后面会回调默认的处理方法
ex.setStackTrace(trace2);
ex.printStackTrace(printWriter);
//把上面获取的堆栈信息转为字符串,打印出来
String stacktrace = result.toString();
printWriter.close();
//Log.v(TAG, "usererror------------------------>" + stacktrace);
getVersion();
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
try{
jsonObject.put("userId",new KFXApp().getUserName());//用户id
jsonObject.put("deviceType","安卓:" + Build.VERSION.RELEASE);//安卓版本信息
jsonObject.put("versionMain",versionMain);//代码大版本
jsonObject.put("versionMini",versionMini);//代码小版本
jsonObject.put("crashStackTrace",stacktrace);//崩溃信息
jsonObject.put("crashTime",formatter.format(new Date()));//崩溃时间
jsonObject.put("phoneInfo","制造商:" + Build.MANUFACTURER + " 手机型号:" + Build.MODEL + " " + Build.BRAND);//手机信息
jsonObject.put("others","");
jsonArray.put(jsonObject);
Log.v(TAG,"json-->" + jsonArray.toString());
}catch(JSONException e){
e.printStackTrace();
}
//以下上传服务器的代码
}
/**
* 获取代码的版本信息
*/
private void getVersion(){
}
}
然后在Application的oncreate()方法中初始化后,即可成功应用。
UserError userError = UserError.getInstance();
userError.init(getApplicationContext());
【完】