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

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

2013-12-04 14:21 573 查看
出发点:

开源的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个,如下所示:

字段 说明

[align=left]字段[/align]
[align=left]说明[/align]
[align=left]platform_id[/align]
[align=left]1 =aPad,2=aPhone[/align]
[align=left]android_version[/align]
[align=left]Android版本号[/align]
[align=left]app_version_code[/align]
[align=left]应用的版本代码 如 9[/align]
[align=left]app_version_name[/align]
[align=left]应用的版本名称 如 1.2.2[/align]
[align=left]device_id[/align]
[align=left]设备的唯一id[/align]
[align=left]model[/align]
[align=left]手机/平板的模型,如BCM63[/align]
[align=left]brand[/align]
[align=left]Android设备牌子,如三星[/align]
[align=left]product[/align]
[align=left]Android产品信息[/align]
[align=left]stack_trace[/align]
[align=left]崩溃的堆栈信息[/align]
[align=left]crash_date[/align]
[align=left]崩溃的时间点[/align]
[align=left]package_name[/align]
[align=left]应用的包名[/align]
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报表,或者直接通过浏览器查看

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