问题
I am using ACRA woth my android app. My question is, when a crash happens, how can I make sure I execute some code before the crash is reported. I mean I would like to add some custom variables when the crash happens so I know what state the app was in?
Please help
Thank you
回答1:
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.
回答2:
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.
回答3:
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);
}
}
来源:https://stackoverflow.com/questions/10854031/acra-with-android-how-to-execute-code-before-crash-is-reported