您的位置:首页 > 移动开发 > Android开发

基于开源项目acra实现的定制化Android crash上报库及后台系统

2012-03-26 22:55 971 查看
出发点: 开源的acra crash上报库(http://code.google.com/p/acra/)的缺点有: 1. crash上报到google doc里的话,由于被墙了,所以看不到数据。 2 如果基于邮件上报crash的话,不方便统计crash崩溃率。3. acra上报的字段过多,需要过滤一些没用的字段。
目的:当Android应用程序崩溃时,可以及时通过浏览器查看到崩溃的堆栈信息,同时后台还可以统计每天的崩溃比率,以方便应用程序的体验改进
实践过程:

1. 首先下载acra的源码svn checkout http://acra.googlecode.com/svn/trunk, 在eclipse中导入该项目,在ACRA.java中发现默认上报的字段内容有:
public static final ReportField[] DEFAULT_REPORT_FIELDS = { REPORT_ID, APP_VERSION_CODE, APP_VERSION_NAME,
PACKAGE_NAME, FILE_PATH, PHONE_MODEL, BRAND, PRODUCT, ANDROID_VERSION, BUILD, TOTAL_MEM_SIZE,
AVAILABLE_MEM_SIZE, CUSTOM_DATA, IS_SILENT, STACK_TRACE, INITIAL_CONFIGURATION, CRASH_CONFIGURATION,
DISPLAY, USER_COMMENT, USER_EMAIL, USER_APP_START_DATE, USER_CRASH_DATE, DUMPSYS_MEMINFO, LOGCAT,
DEVICE_ID, INSTALLATION_ID, DEVICE_FEATURES, ENVIRONMENT, SHARED_PREFERENCES, SETTINGS_SYSTEM,
SETTINGS_SECURE };


2.过滤一些无用的字段,当Android应用崩溃后,需要统计的数据只有11个,如下所示:

字段 说明
字段
说明
platform_id
1 =aPad,2=aPhone
android_version
Android版本号
app_version_code
应用的版本代码 如 9
app_version_name
应用的版本名称 如 1.2.2
device_id
设备的唯一id
model
手机/平板的模型,如BCM63
brand
Android设备牌子,如三星
product
Android产品信息
stack_trace
崩溃的堆栈信息
crash_date
崩溃的时间点
package_name
应用的包名
Firgure 1 上报字段

在ACRA.java中的addReportSenders函数中增加Figure1中上报字段的映射:
if (conf.formUri() != null && !"".equals(conf.formUri())) {

Map<ReportField, String> mapField = new HashMap<ReportField,String>();
mapField.put(ReportField.ANDROID_VERSION, "android_version");
mapField.put(ReportField.APP_VERSION_CODE, "app_version_code");
mapField.put(ReportField.APP_VERSION_NAME, "app_version_name");
mapField.put(ReportField.DEVICE_ID, "device_id");
mapField.put(ReportField.PHONE_MODEL, "model");
mapField.put(ReportField.BRAND, "brand");
mapField.put(ReportField.PRODUCT, "product");
mapField.put(ReportField.STACK_TRACE, "stack_trace");
mapField.put(ReportField.USER_CRASH_DATE, "crash_date");
mapField.put(ReportField.PACKAGE_NAME, "package_name");
errorReporter.addReportSender(new HttpPostSender(conf.formUri(), mapField));
return;
}


在HttpPostSender.java中的remap函数中修改如下:
for (ReportField field : fields) {
/* if (mMapping == null || mMapping.get(field) == null) {
finalReport.put(field.toString(), report.get(field));
} else {
finalReport.put(mMapping.get(field), report.get(field));
}*/
if(mMapping!=null && mMapping.get(field) != null){

finalReport.put(mMapping.get(field), report.get(field));
}

}
finalReport.put("platform_id", ACRA.getConfig().platformId());

3. 修改完后,只需要在应用程序中增加如下几行代码,就可以实时的上报崩溃的堆栈信息(这点比ios平台方便)
@ReportsCrashes(formKey = "", // will not be used
platformId="1",
formUriBasicAuthLogin = "user",
formUriBasicAuthPassword = "password",
formUri = "http://weiwangzi.com:8080/CrashReport/CrashServerlet")
public class TestApplication extends Application {

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
ACRA.init(this);
}


4. 实现serverlet来统计上报的crash数据到数据库中
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

Connection conn = null;
PreparedStatement pstmt = null;
try{
conn = DBUtil.getConnection();
String platformId=request.getParameter("platform_id");
String androidVersion=request.getParameter("android_version");
String appVersionCode=request.getParameter("app_version_code");
String appVersionName=request.getParameter("app_version_name");
String deviceId=request.getParameter("device_id");
String model=request.getParameter("model");
String brand=request.getParameter("brand");
String product=request.getParameter("product");
String stackTrace=request.getParameter("stack_trace");
String crashDate=request.getParameter("crash_date");
String packageName=request.getParameter("package_name");
pstmt = conn.prepareStatement("insert into report(platform_id, android_version, app_version_code,appversion_name,device_id,model,brand,product,stack_trace,crash_date,package_name) values (?, ?, ?,?,?,?,?,?,?,?,?)");
pstmt.setString(1, platformId);
pstmt.setString(2, androidVersion);
pstmt.setString(3, appVersionCode);
pstmt.setString(4, appVersionName);
pstmt.setString(5, deviceId);
pstmt.setString(6, model);
pstmt.setString(7, brand);
pstmt.setString(8, product);
pstmt.setString(9, stackTrace);
pstmt.setString(10, crashDate);
pstmt.setString(11, packageName);
pstmt.executeUpdate();

}catch(Exception e){
e.printStackTrace();

}finally{
if(pstmt!=null){
try {
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
}

}


实践结果:通过数据库可以导出一个excel的crash报表,或者直接通过浏览器查看

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐