如何自定义ACRA错误上报的JSON请求体为指定格式?
自定义ACRA错误上报的JSON请求体格式
完全可以实现你需要的嵌套JSON格式上报,仅靠putCustomData()无法满足嵌套结构需求,你需要通过自定义HttpSender或者实现ReportSender接口来重新组织上报数据的结构。
方法一:自定义HttpSender(推荐,基于ACRA原生扩展)
ACRA的HttpSender是默认的HTTP上报类,你可以重写它的createHttpEntity()方法,重新构建符合要求的JSON结构:
1. 创建自定义HttpSender类
import org.acra.config.CoreConfiguration; import org.acra.data.CrashReportData; import org.acra.sender.HttpSender; import org.acra.ReportField; import org.json.JSONException; import org.json.JSONObject; public class CustomHttpSender extends HttpSender { public CustomHttpSender(Method method, String url, String basicAuthLogin, String basicAuthPassword) { super(method, url, basicAuthLogin, basicAuthPassword); } @Override protected JSONObject createHttpEntity(CoreConfiguration config, CrashReportData report) throws JSONException { // 构建最终上报的JSON对象 JSONObject finalReport = new JSONObject(); // 添加自定义error_message,这里示例取栈顶错误信息,也可设固定文本 String errorMsg = report.getString(ReportField.STACK_TRACE).split("\n")[0]; finalReport.put("error_message", errorMsg); // 构建dispo_info嵌套对象,填充原有报告字段 JSONObject dispoInfo = new JSONObject(); dispoInfo.put("REPORT_ID", report.getString(ReportField.REPORT_ID)); dispoInfo.put("APP_VERSION_CODE", report.getString(ReportField.APP_VERSION_CODE)); dispoInfo.put("APP_VERSION_NAME", report.getString(ReportField.APP_VERSION_NAME)); dispoInfo.put("ANDROID_VERSION", report.getString(ReportField.ANDROID_VERSION)); dispoInfo.put("STACK_TRACE", report.getString(ReportField.STACK_TRACE)); finalReport.put("dispo_info", dispoInfo); return finalReport; } }
2. 配置ACRA使用自定义Sender
通过注解或者代码配置ACRA,指定使用你的CustomHttpSender:
注解方式(在Application类上)
import org.acra.annotation.AcraCore; import org.acra.annotation.AcraHttpSender; import org.acra.sender.HttpSender; @AcraCore(buildConfigClass = BuildConfig.class) @AcraHttpSender( httpMethod = HttpSender.Method.POST, uri = "你的API上报地址", senderClass = CustomHttpSender.class ) public class MyApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); ACRA.init(this); } }
代码配置方式
import org.acra.config.CoreConfigurationBuilder; import org.acra.config.SenderConfigurationBuilder; import org.acra.sender.HttpSenderBuilder; // 在Application的attachBaseContext或onCreate中初始化 ACRA.init(this, new CoreConfigurationBuilder() .withBuildConfigClass(BuildConfig.class) .withSenderConfiguration(new SenderConfigurationBuilder() .withHttpSender(new HttpSenderBuilder() .withHttpMethod(HttpSender.Method.POST) .withUri("你的API上报地址") .withSenderClass(CustomHttpSender.class)) .build()) .build());
方法二:实现ReportSender接口(完全自定义上报逻辑)
如果需要更灵活的控制(比如用OkHttp发送请求),可以直接实现ReportSender接口,完全自定义上报流程:
1. 创建自定义ReportSender类
import org.acra.config.CoreConfiguration; import org.acra.data.CrashReportData; import org.acra.sender.ReportSender; import org.acra.sender.ReportSenderException; import org.acra.ReportField; import org.json.JSONException; import org.json.JSONObject; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import java.io.IOException; public class CustomReportSender implements ReportSender { private final String apiUrl; private final OkHttpClient okHttpClient = new OkHttpClient(); public CustomReportSender(String apiUrl) { this.apiUrl = apiUrl; } @Override public void send(CoreConfiguration config, CrashReportData report) throws ReportSenderException { try { JSONObject finalReport = new JSONObject(); // 自定义error_message内容 finalReport.put("error_message", "This is a test error message."); JSONObject dispoInfo = new JSONObject(); dispoInfo.put("REPORT_ID", report.getString(ReportField.REPORT_ID)); dispoInfo.put("APP_VERSION_CODE", report.getString(ReportField.APP_VERSION_CODE)); dispoInfo.put("APP_VERSION_NAME", report.getString(ReportField.APP_VERSION_NAME)); dispoInfo.put("ANDROID_VERSION", report.getString(ReportField.ANDROID_VERSION)); dispoInfo.put("STACK_TRACE", report.getString(ReportField.STACK_TRACE)); finalReport.put("dispo_info", dispoInfo); // 构建JSON请求体 RequestBody requestBody = RequestBody.create( finalReport.toString(), MediaType.parse("application/json; charset=utf-8") ); // 发送POST请求 Request request = new Request.Builder() .url(apiUrl) .post(requestBody) .build(); okHttpClient.newCall(request).execute(); } catch (JSONException | IOException e) { throw new ReportSenderException("上报错误失败", e); } } }
2. 配置ACRA使用该Sender
ACRA.init(this, new CoreConfigurationBuilder() .withBuildConfigClass(BuildConfig.class) .withSenderConfiguration(new SenderConfigurationBuilder() .withReportSender(new CustomReportSender("你的API上报地址")) .build()) .build());
关键说明
putCustomData()只能添加顶级键值对,无法创建嵌套的dispo_info对象结构,因此无法直接实现你的需求。- 两种方法中,自定义
HttpSender更贴合ACRA的原生设计,无需额外引入网络库;实现ReportSender则适合需要完全自定义请求逻辑的场景。
内容的提问来源于stack exchange,提问作者CactusJack
相关产品推荐
相关产品推荐

