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

ACRA 5.9版本HttpSender重复发送错误报告问题求助

问题

升级ACRA至5.9版本后,出现错误报告重复发送的问题:

  • 使用自定义HttpSender时,报告被发送4次
  • 仅使用内置HttpSender时,报告被发送2次
  • 即使在ACRA配置中禁用内置HttpSender,仍会创建多个自定义HttpSender并发送2次报告

ACRA初始化代码

ACRA.init(this, new CoreConfigurationBuilder()
    .withBuildConfigClass(BuildConfig.class)
    .withReportFormat(StringFormat.KEY_VALUE_LIST)
    .withPluginConfigurations(
                    new ToastConfigurationBuilder()
                                    .withText(getString(R.string.crash_toast_text))
                                    .build()
                    )
    .withPluginConfigurations(
                    BuildConfig.DEBUG ?
                    new LimiterConfigurationBuilder()
                                    .withPeriod(1)
                                    .withPeriodUnit(TimeUnit.DAYS)
                                    .withOverallLimit(250)
                                    .withExceptionClassLimit(100)
                                    .withStacktraceLimit(50)
                                    .withFailedReportLimit(50)
                                    .withIgnoredCrashToast("App stopped working again")
                                    .build() :
                    new LimiterConfigurationBuilder()
                                    .withPeriod(7)
                                    .withPeriodUnit(TimeUnit.DAYS)
                                    .withOverallLimit(25)
                                    .withExceptionClassLimit(10)
                                    .withStacktraceLimit(5)
                                    .withFailedReportLimit(5)
                                    .withIgnoredCrashToast("App stopped working again")
                                    .build()
    )
    .withPluginConfigurations(
                    new HttpSenderConfigurationBuilder()
                                    .withConnectionTimeout(8000)
                                    .withDropReportsOnTimeout(true)
                                    .withUri(fs.getCrashReportUrl())
                                    .build()
    )
    .withReportContent(fields)
);

自定义HttpSender实现

@AutoService(ReportSenderFactory.class)
public class MyCrashSenderFactory implements ReportSenderFactory {

    private static final String TAG = MyCrashSenderFactory.class.getSimpleName();

    @NonNull
    public ReportSender create(@NonNull Context context, @NonNull CoreConfiguration config) {

        MySettings fs = new MySettings(context);
        if (BuildConfig.DEBUG) Log.d(TAG,"ACRA create sender for "+fs.getCrashReportUrl());
        return new HttpSender(config, HttpSender.Method.POST, StringFormat.KEY_VALUE_LIST, fs.getCrashReportUrl());
    }

    @Override
    public boolean enabled(@NonNull CoreConfiguration coreConfig) {
        return true;
    }
}

崩溃后日志

14:17:25.358  E  ACRA caught a ArithmeticException for com.myapp
                 java.lang.ArithmeticException: divide by zero
                    at com.myapp.MenuItemHandler.handleMenuClick(MenuItemHandler.java:128)
...
14:17:25.452  D  ACRA create sender for https://api.myapp.com/api/error_report.php
14:17:25.468  D  ACRA create sender for https://api.myapp.com/api/error_report.php
14:17:25.511  E  USNET: appName: com.myapp:acra
---------------------------- PROCESS STARTED (2569) for package com.myapp ----------------------------
---------------------------- PROCESS ENDED (2036) for package com.myapp ----------------------------
14:17:25.896  D  ACRA registered
14:17:25.983  D  ACRA create sender for https://api.myapp.com/api/error_report.php
14:17:26.006  I  Sending report /data/user/0/com.myapp/app_ACRA-approved/2023-02-11T14:17:25.380+07:00.stacktrace
---------------------------- PROCESS STARTED (2606) for package com.myapp ----------------------------
14:17:27.088  I  ACRA is enabled for com.myapp, initializing...
14:17:27.227  D  ACRA create sender for https://api.myapp.com/api/error_report.php
14:17:27.237  D  ACRA create sender for https://api.myapp.com/api/error_report.php
14:17:27.277  D  ACRA create sender for https://api.myapp.com/api/error_report.php
14:17:27.278  I  Sending report /data/user/0/com.myapp/app_ACRA-approved/2023-02-11T14:17:25.380+07:00.stacktrace
14:17:27.732  I  Request received by server
14:17:28.318  I  Request received by server
14:17:28.907  I  Request received by server
14:17:29.863  I  Request received by server
14:17:29.868  W  Could not delete file: /data/user/0/com.myapp/app_ACRA-approved/2023-02-11T14:17:25.380+07:00.stacktrace

补充日志(禁用内置HttpSender后)

---------------------------- PROCESS ENDED (15606) for package com.myapp ----------------------------
---------------------------- PROCESS STARTED (15894) for package com.myapp ----------------------------
08:50:18.794 15894-15894 com.myapp  I  ACRA is enabled for com.myapp, initializing...
08:50:36.376 15894-15894 com.myapp  E  ACRA caught a ArithmeticException for com.myapp
                                                                     java.lang.ArithmeticException: divide by zero
                                                                        at com.myapp.MenuItemHandler.handleMenuClick(MenuItemHandler.java:128)
...
08:50:36.457 15894-15894 com.myapp  D  ACRA create sender for https://api.myapp.com/api/error_report.php
08:50:36.466 15894-15894 com.myapp  D  ACRA create sender for https://api.myapp.com/api/error_report.php
08:50:36.539 16093-16093 pid-16093E  USNET: appName: com.myapp:acra
---------------------------- PROCESS STARTED (16093) for package com.myapp ----------------------------
---------------------------- PROCESS ENDED (15894) for package com.myapp ----------------------------
08:50:36.599 16093-16093 com.myapp  D  handleBindApplication()++ app=com.myapp:acra
08:50:37.040 16093-16120 com.myapp  D  ACRA create sender for https://api.myapp.com/api/error_report.php
08:50:37.063 16093-16120 com.myapp  I  Sending report /data/user/0/com.myapp/app_ACRA-approved/2023-02-12T08:50:36.395+07:00.stacktrace
---------------------------- PROCESS STARTED (16128) for package com.myapp ----------------------------
08:50:38.208 16128-16128 com.myapp  I  ACRA is enabled for com.myapp, initializing...
08:50:38.334 16128-16158 com.myapp  D  ACRA create sender for https://api.myapp.com/api/error_report.php
08:50:38.341 16128-16158 com.myapp  D  ACRA create sender for https://api.myapp.com/api/error_report.php
08:50:38.381 16093-16160 com.myapp  D  ACRA create sender for https://api.myapp.com/api/error_report.php
08:50:38.382 16093-16160 com.myapp  I  Sending report /data/user/0/com.myapp/app_ACRA-approved/2023-02-12T08:50:36.395+07:00.stacktrace
08:50:38.824 16093-16120 com.myapp  I  Request received by server
08:50:39.916 16093-16160 com.myapp  I  Request received by server
08:50:39.925 16093-16160 com.myapp  W  Could not delete file: /data/user/0/com.myapp/app_ACRA-approved/2023-02-12T08:50:36.395+07:00.stacktrace
解决方案

问题根源

  1. Sender重复注册:自定义的MyCrashSenderFactory使用@AutoService(ReportSenderFactory.class),ACRA会自动扫描注册该Sender;同时初始化代码里又通过HttpSenderConfigurationBuilder添加了内置HttpSender,导致同一报告被两个Sender各发送一次。
  2. 进程重启+文件删除失败:崩溃后ACRA会启动独立进程发送报告,若原进程重启后再次触发报告发送,加上日志中出现的Could not delete file错误,已发送的报告文件未被删除,会被重复处理发送。

修复步骤

1. 避免Sender重复注册(二选一)

方案A:移除初始化代码中的内置HttpSender配置

删除初始化代码里的这段配置:

.withPluginConfigurations(
                new HttpSenderConfigurationBuilder()
                                .withConnectionTimeout(8000)
                                .withDropReportsOnTimeout(true)
                                .withUri(fs.getCrashReportUrl())
                                .build()
)

仅保留自定义SenderFactory的自动注册即可。

方案B:禁用自定义SenderFactory的自动注册

  • 去掉MyCrashSenderFactory类上的@AutoService(ReportSenderFactory.class)注解
  • 在初始化代码中手动注册自定义Sender:
.withPluginConfigurations(new ReportSenderConfigurationBuilder()
                .withSenderFactory(MyCrashSenderFactory.class)
                .build())

同时删除内置HttpSender的配置,避免重复。

2. 解决报告文件无法删除的问题

  • 检查应用对app_ACRA-approved目录的读写权限,确保ACRA有删除文件的权限
  • 若使用Android 10及以上版本,确认是否启用了分区存储,必要时调整ACRA的报告存储路径到应用私有目录(ACRA默认路径已是私有目录,若自定义路径需确保合法)

3. 防止ACRA重复初始化

  • 检查Application的onCreate方法,确保ACRA只初始化一次,可通过判断进程名避免多进程场景下重复初始化:
if (!isAcraProcess()) {
    ACRA.init(...);
}

private boolean isAcraProcess() {
    String processName = "";
    int pid = android.os.Process.myPid();
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
        if (processInfo.pid == pid) {
            processName = processInfo.processName;
            break;
        }
    }
    return processName != null && processName.endsWith(":acra");
}

内容的提问来源于stack exchange,提问作者Alexey Ozerov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:25:30