You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 15:04:57