ACRA with android: How to execute code before crash is reported

走远了吗. 提交于 2019-12-01 22:03:06

Implement your own sender as described here. It can be simply a wrapper around some existing sender, forwarding the sending functionality there.

Inside the sender code, you can take any special actions before actually sending the report.

This is what worked for me using ACRA 4.5.0 with the HttpSender backend. I am using Acralyzer on Cloudant.

Original code:

@ReportsCrashes(
    mode = ReportingInteractionMode.DIALOG,
    resDialogText = R.string.crash_dialog_text,
    resDialogCommentPrompt = R.string.crash_dialog_comment_prompt,

    formUri = "https://kpc.cloudant.com/acra-openconnect/_design/acra-storage/_update/report",
    formUriBasicAuthLogin="[restricted reporter login]",
    formUriBasicAuthPassword="[restricted reporter password]",
    reportType = org.acra.sender.HttpSender.Type.JSON,
    httpMethod = org.acra.sender.HttpSender.Method.PUT,

    formKey = ""
)

public class Application extends android.app.Application {

    public void onCreate() {
        super.onCreate();
        ACRA.init(this);

My application keeps an in-memory circular buffer with log messages. This doesn't get written to disk, and I didn't particularly want to render it into a string and call putCustomData() every time an entry was added. So instead, I call my static "dumper" method, VPNLog.dumpLast(), to modify the report right before HttpSender.send() runs. The new code looks like this:

@ReportsCrashes(
    mode = ReportingInteractionMode.DIALOG,
    resDialogText = R.string.crash_dialog_text,
    resDialogCommentPrompt = R.string.crash_dialog_comment_prompt,

    formUri = "https://kpc.cloudant.com/acra-openconnect/_design/acra-storage/_update/report",
    formUriBasicAuthLogin="[restricted reporter login]",
    formUriBasicAuthPassword="[restricted reporter password]",
    // reportType and httpMethod are now defined below

    formKey = ""
)

public class Application extends android.app.Application {

    public void onCreate() {
        super.onCreate();
        ACRA.init(this);
        ACRA.getErrorReporter().setReportSender(
            new HttpSender(org.acra.sender.HttpSender.Method.PUT,
                           org.acra.sender.HttpSender.Type.JSON,
                           null) {

                @Override
                public void send(CrashReportData report) throws ReportSenderException {
                    report.put(ReportField.APPLICATION_LOG, VPNLog.dumpLast());
                    super.send(report);
                }

            });

The value I'm adding is a long (100+ line) string; Acralyzer correctly breaks it into separate numbered lines.

Another option is to populate ReportField.CUSTOM_DATA with multiple key/value pairs:

report.put(ReportField.CUSTOM_DATA, "key0=value0\nkey1=value1\n");

Acralyzer will display these in an HTML table.

Acra works by using Thread.setDefaultUncaughtExceptionHandler(...);

You can set your own uncaught exception handler, and then call ACRA to generate a report:

public class My_Exception_Interceptor implements Thread.UncaughtExceptionHandler {

    /**
     * Sets up to catch an exception. 
     * Call this after initializing ACRA.
     */
    public void setUpFatalExceptionHandling() {
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * Called by the JVM on an uncaught exception. 
     * @param t - the thread
     * @param e - the throwable
     */
    @Override
    public void uncaughtException(@Nullable Thread t, @NonNull Throwable e) {
        ...your code...
        ACRA.getErrorReporter().handleException(e, true);
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!