Ich möchte einen globalen nicht erfassten Ausnahmebehandler für alle Threads in meiner Android-Anwendung festlegen. Daher habe Application
ich in meiner Unterklasse eine Implementierung Thread.UncaughtExceptionHandler
als Standardhandler für nicht erfasste Ausnahmen festgelegt.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
In meiner Implementierung versuche ich, eine AlertDialog
entsprechende Ausnahmemeldung anzuzeigen.
Dies scheint jedoch nicht zu funktionieren. Immer wenn eine Ausnahme für einen Thread ausgelöst wird, der nicht behandelt wird, wird der Standarddialog für das Betriebssystem angezeigt ("Entschuldigung! -Anwendung wurde unerwartet gestoppt").
Was ist der richtige und ideale Weg, um einen Standardhandler für nicht erfasste Ausnahmen festzulegen?
Antworten:
Das sollte alles sein, was Sie tun müssen. (Stellen Sie sicher, dass der Prozess danach angehalten wird - die Dinge könnten sich in einem unsicheren Zustand befinden.)
Als erstes muss überprüft werden, ob der Android-Handler noch aufgerufen wird. Es ist möglich, dass Ihre Version aufgerufen wird, aber tödlich fehlschlägt und der system_server ein generisches Dialogfeld anzeigt, wenn der Prozess abstürzt.
Fügen Sie oben in Ihrem Handler einige Protokollnachrichten hinzu, um festzustellen, ob sie dort ankommen. Drucken Sie das Ergebnis von getDefaultUncaughtExceptionHandler und lösen Sie dann eine nicht erfasste Ausnahme aus, um einen Absturz zu verursachen. Behalten Sie die Logcat-Ausgabe im Auge, um zu sehen, was los ist.
quelle
Ich habe vor langer Zeit die einfache Lösung für die benutzerdefinierte Behandlung von Android-Abstürzen veröffentlicht. Es ist ein wenig hackig, funktioniert aber auf allen Android-Versionen (einschließlich Lollipop).
Zuerst ein bisschen Theorie. Die Hauptprobleme bei der Verwendung des nicht erfassten Ausnahmehandlers in Android sind die Ausnahmen, die im Hauptthread (auch als UI-Thread bezeichnet) ausgelöst werden. Und hier ist warum. Wenn die App gestartet wird, ruft das System die ActivityThread.main- Methode auf, die den Main Looper Ihrer App vorbereitet und startet :
Der Hauptschleifer ist für die Verarbeitung der im UI-Thread veröffentlichten Nachrichten verantwortlich (einschließlich aller Nachrichten im Zusammenhang mit dem Rendern und der Interaktion der UI). Wenn eine Ausnahme im UI-Thread ausgelöst wird, wird sie von Ihrem Exception-Handler abgefangen. Da Sie
loop()
jedoch keine Methode mehr haben, können Sie dem Benutzer keine Dialoge oder Aktivitäten anzeigen, da niemand mehr übrig ist, um UI-Nachrichten zu verarbeiten für dich.Die vorgeschlagene Lösung ist recht einfach. Wir führen die
Looper.loop
Methode selbst aus und umgeben sie mit einem Try-Catch-Block. Wenn eine Ausnahme abgefangen wird, verarbeiten wir sie wie gewünscht (z. B. starten Sie unsere benutzerdefinierte Berichtsaktivität) und rufen dieLooper.loop
Methode erneut auf.Die folgende Methode demonstriert diese Technik (sie sollte vom
Application.onCreate
Listener aufgerufen werden ):Wie Sie sehen können, wird der nicht erfasste Ausnahmebehandler nur für die Ausnahmen verwendet, die in Hintergrundthreads ausgelöst werden. Der folgende Handler fängt diese Ausnahmen ab und gibt sie an den UI-Thread weiter:
Ein Beispielprojekt, das diese Technik verwendet, ist auf meinem GitHub-Repo verfügbar: https://github.com/idolon-github/android-crash-catcher
quelle
java.lang.RuntimeException: Performing pause of activity that is not resumed
. Ich glaube, wenn ich versuche, meinen eigenen Looper zu starten, pausiert das System die Aktivität, die gerade gestartet wird. Ich bin nicht sicher, aber jede Hilfe wäre dankbar. DankeFWIW Ich weiß, dass dies etwas vom Thema abweicht, aber wir haben den kostenlosen Plan von Crittercism mit Erfolg angewendet . Sie bieten auch einige Premium-Funktionen, wie die Behandlung der Ausnahme, damit die App nicht abstürzt.
In der kostenlosen Version sieht der Benutzer den Absturz immer noch, aber zumindest erhalte ich die E-Mail und den Stack-Trace.
Wir verwenden auch die iOS-Version (aber ich habe von meinen Kollegen gehört, dass es nicht ganz so gut ist).
Hier sind ähnliche Fragen:
quelle
Ich denke, um zu deaktivieren, dass in Ihrer uncaughtException () -Methode nicht previousHandler.uncaughtException () aufgerufen wird, wobei previousHandler von festgelegt ist
quelle
Es funktioniert nicht, bis Sie anrufen
ganz am Ende Ihres UncaughtExceptionHandler.
quelle