diff --git a/src/main/java/org/acra/builder/ReportExecutor.java b/src/main/java/org/acra/builder/ReportExecutor.java index 88f1f4478d..170e13780d 100644 --- a/src/main/java/org/acra/builder/ReportExecutor.java +++ b/src/main/java/org/acra/builder/ReportExecutor.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.Debug; import android.os.Looper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -236,7 +237,23 @@ private void dialogAndEnd(@NonNull ReportBuilder reportBuilder, @NonNull File re if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Wait for Toast + worker ended. Kill Application ? " + reportBuilder.isEndApplication()); if (reportBuilder.isEndApplication()) { - endApplication(reportBuilder.getUncaughtExceptionThread(), reportBuilder.getException()); + if(Debug.isDebuggerConnected()){ + //Killing a process with a debugger attached would kill the whole application, so don't do that. + final String warning = "Warning: Acra may behave differently with a debugger attached"; + new Thread() { + @Override + public void run() { + Looper.prepare(); + Toast.makeText(context, warning, Toast.LENGTH_LONG).show(); + Looper.loop(); + } + }.start(); + ACRA.log.w(LOG_TAG, warning); + //do as much cleanup as we can without killing the process + finishLastActivity(reportBuilder.getUncaughtExceptionThread()); + }else { + endApplication(reportBuilder.getUncaughtExceptionThread(), reportBuilder.getException()); + } } } @@ -252,33 +269,36 @@ private void endApplication(@Nullable Thread uncaughtExceptionThread, Throwable if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Handing Exception on to default ExceptionHandler"); defaultExceptionHandler.uncaughtException(uncaughtExceptionThread, th); } else { + finishLastActivity(uncaughtExceptionThread); // If ACRA handles user notifications with a Toast or a Notification // the Force Close dialog is one more notification to the user... // We choose to close the process ourselves using the same actions. - // Trying to solve https://github.com/ACRA/acra/issues/42#issuecomment-12134144 - // Determine the current/last Activity that was started and close - // it. Activity#finish (and maybe it's parent too). - final Activity lastActivity = lastActivityManager.getLastActivity(); - if (lastActivity != null) { - if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Finishing the last Activity prior to killing the Process"); - lastActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - lastActivity.finish(); - if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Finished " + lastActivity.getClass()); - } - }); + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(10); + } + } - // A crashed activity won't continue its lifecycle. So we only wait if something else crashed - if (uncaughtExceptionThread != lastActivity.getMainLooper().getThread()) { - lastActivityManager.waitForActivityStop(100); + private void finishLastActivity(Thread uncaughtExceptionThread){ + // Trying to solve https://github.com/ACRA/acra/issues/42#issuecomment-12134144 + // Determine the current/last Activity that was started and close + // it. Activity#finish (and maybe it's parent too). + final Activity lastActivity = lastActivityManager.getLastActivity(); + if (lastActivity != null) { + if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Finishing the last Activity prior to killing the Process"); + lastActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + lastActivity.finish(); + if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Finished " + lastActivity.getClass()); } - lastActivityManager.clearLastActivity(); - } + }); - android.os.Process.killProcess(android.os.Process.myPid()); - System.exit(10); + // A crashed activity won't continue its lifecycle. So we only wait if something else crashed + if (uncaughtExceptionThread != lastActivity.getMainLooper().getThread()) { + lastActivityManager.waitForActivityStop(100); + } + lastActivityManager.clearLastActivity(); } }