android exception-handling uncaught-exception

Forma ideal de establecer la excepción global no detectada Handler en Android



exception-handling uncaught-exception (5)

Creo que para deshabilitar eso en su método uncaughtException () no llame a previousHandler.uncaughtException () donde se establece previousHandler

previousHandler = Thread.getDefaultUncaughtExceptionHandler();

Quiero configurar un controlador global de excepciones no detectadas para todos los hilos en mi aplicación Android. Por lo tanto, en mi subclase de Application establezco una implementación de Thread.UncaughtExceptionHandler como controlador predeterminado para las excepciones no detectadas.

Thread.setDefaultUncaughtExceptionHandler( new DefaultExceptionHandler(this));

En mi implementación, intento mostrar un AlertDialog muestre el mensaje de excepción apropiado.

Sin embargo, esto no parece funcionar. Cada vez que se lanza una excepción para un hilo que no se maneja, obtengo el cuadro de diálogo estándar, OS-default (diálogo "Sorry! -Application-has-stopped-unexpectedly").

¿Cuál es la forma correcta e ideal de establecer un controlador predeterminado para las excepciones no detectadas?


Eso debería ser todo lo que necesita hacer. (Asegúrese de hacer que el proceso se detenga después; las cosas podrían estar en un estado incierto).

Lo primero que debes comprobar es si aún se llama al controlador de Android. Es posible que se llame a su versión pero falle fatalmente y que system_server muestre un diálogo genérico cuando vea que el proceso falla.

Agregue algunos mensajes de registro en la parte superior de su controlador para ver si está llegando. Imprima el resultado de getDefaultUncaughtExceptionHandler y luego ejecute una excepción no detectada para provocar un bloqueo. Esté atento a la salida de logcat para ver qué está pasando.


FWIW Sé que esto está un poco fuera de tema, pero hemos estado usando el plan gratuito de Crittercism con éxito. También ofrecen algunas funciones premium, como manejar la excepción para que la aplicación no se cuelgue.

En la versión gratuita, el usuario todavía ve el bloqueo, pero al menos recibo el correo electrónico y el seguimiento de la pila.

También usamos la versión de iOS (pero he escuchado de mis colegas que no es tan buena).

Aquí hay preguntas similares:


No funciona hasta que llame

android.os.Process.killProcess(android.os.Process.myPid());

al final de su UncaughtExceptionHandler.


Publiqué la solution simple para el manejo personalizado de los bloqueos de Android hace mucho tiempo. Es un poco raro, pero funciona en todas las versiones de Android (incluido el Lollipop).

Primero un poco de teoría. Los problemas principales cuando utiliza el controlador de excepciones no detectadas en Android vienen con las excepciones lanzadas en el hilo principal (también conocido como UI). Y aquí está el por qué. Cuando la aplicación se inicia, el sistema llama al método ActivityThread.main que prepara e inicia el Looper principal de su aplicación:

public static void main(String[] args) { … … Looper.prepareMainLooper(); … Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

Main Looper es responsable de procesar los mensajes publicados en el hilo de la interfaz de usuario (incluidos todos los mensajes relacionados con la representación e interacción de la interfaz de usuario). Si se lanza una excepción en el hilo de la interfaz de usuario, su manejador de excepciones lo detectará, pero como está fuera del método loop() no podrá mostrar ningún diálogo o actividad al usuario, ya que no queda nadie para procesar mensajes de UI por usted.

La solución propuesta es bastante simple. Looper.loop método Looper.loop por nuestra cuenta y lo rodeamos con un bloque try-catch. Cuando se Looper.loop una excepción, la procesamos como queremos (por ejemplo, comenzamos nuestra actividad de informe personalizado) y Looper.loop llamar Looper.loop método Looper.loop .

El siguiente método demuestra esta técnica (debe invocarse desde el oyente Application.onCreate ):

private void startCatcher() { UncaughtExceptionHandler systemUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler(); // the following handler is used to catch exceptions thrown in background threads Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler(new Handler())); while (true) { try { Looper.loop(); Thread.setDefaultUncaughtExceptionHandler(systemUncaughtHandler); throw new RuntimeException("Main thread loop unexpectedly exited"); } catch (Throwable e) { showCrashDisplayActivity(e); } } }

Como puede ver, el manejador de excepciones no detectadas se usa solo para las excepciones lanzadas en los hilos de fondo. El siguiente controlador detecta esas excepciones y las propaga al hilo de la interfaz de usuario:

static class UncaughtHandler implements UncaughtExceptionHandler { private final Handler mHandler; UncaughtHandler(Handler handler) { mHandler = handler; } public void uncaughtException(Thread thread, final Throwable e) { mHandler.post(new Runnable() { public void run() { throw new BackgroundException(e); } }); } }

Un proyecto de ejemplo que utiliza esta técnica está disponible en mi repositorio de GitHub: https://github.com/idolon-github/android-crash-catcher