Quero definir um manipulador global de exceção não capturada para todos os threads em meu aplicativo Android. Portanto, em minha Application
subclasse, defini uma implementação de Thread.UncaughtExceptionHandler
como manipulador padrão para exceções não detectadas.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
Em minha implementação, estou tentando exibir uma AlertDialog
mensagem de exceção apropriada exibindo.
No entanto, isso não parece funcionar. Sempre que, uma exceção é lançada para qualquer thread que não foi tratada, eu obtenho o estoque, caixa de diálogo padrão do SO ("Desculpe! Diálogo de aplicativo parou inesperadamente").
Qual é a maneira correta e ideal de definir um manipulador padrão para exceções não detectadas?
Respostas:
Isso deve ser tudo que você precisa fazer. (Certifique-se de fazer com que o processo pare depois - as coisas podem estar em um estado incerto.)
A primeira coisa a verificar é se o manipulador Android ainda está sendo chamado. É possível que sua versão esteja sendo chamada, mas falhando fatalmente e o system_server esteja mostrando uma caixa de diálogo genérica ao ver a falha do processo.
Adicione algumas mensagens de log no topo do seu manipulador para ver se ele está chegando lá. Imprima o resultado de getDefaultUncaughtExceptionHandler e, em seguida, lance uma exceção não capturada para causar um travamento. Fique de olho na saída do logcat para ver o que está acontecendo.
fonte
Publiquei a solução simples para tratamento personalizado de travamentos do Android há muito tempo. É um pouco hacky, no entanto, funciona em todas as versões do Android (incluindo o Lollipop).
Primeiro um pouco de teoria. Os principais problemas ao usar o manipulador de exceções não detectadas no Android vêm com as exceções lançadas no thread principal (também conhecido como UI). E aqui está o porquê. Quando o aplicativo é iniciado, o sistema chama o método ActivityThread.main , que prepara e inicia o looper principal do seu aplicativo:
O looper principal é responsável por processar as mensagens postadas no thread da IU (incluindo todas as mensagens relacionadas à renderização e interação da IU). Se uma exceção for lançada no thread de IU, ela será capturada por seu manipulador de exceções, mas como você está fora do
loop()
método, não será capaz de mostrar nenhuma caixa de diálogo ou atividade ao usuário, pois não sobrou ninguém para processar mensagens de IU para voce.A solução proposta é bastante simples. Executamos o
Looper.loop
método por conta própria e o envolvemos com o bloco try-catch. Quando uma exceção é detectada, nós a processamos como queremos (por exemplo, iniciamos nossa atividade de relatório personalizado) e chamamos oLooper.loop
método novamente.O método a seguir demonstra essa técnica (deve ser chamado a partir do
Application.onCreate
ouvinte):Como você pode ver, o manipulador de exceções não capturadas é usado apenas para as exceções lançadas em threads de fundo. O manipulador a seguir captura essas exceções e as propaga para o thread de IU:
Um exemplo de projeto que usa essa técnica está disponível no meu repositório GitHub: https://github.com/idolon-github/android-crash-catcher
fonte
java.lang.RuntimeException: Performing pause of activity that is not resumed
. Acredito que quando estou tentando iniciar meu próprio looper o sistema pausa a atividade que está prestes a começar? Não tenho certeza, mas qualquer ajuda seria apreciada. ObrigadoEu acho que para desativar isso em seu método uncaughtException () não chame previousHandler.uncaughtException () onde previousHandler é definido por
fonte
FWIW Eu sei que isso é um pouco fora do assunto, mas temos usado o plano gratuito do Crittercism com sucesso. Eles também oferecem alguns recursos premium, como lidar com a exceção para que o aplicativo não trave.
Na versão gratuita, o usuário ainda vê o travamento, mas pelo menos recebo o e-mail e o rastreamento da pilha.
Também usamos a versão iOS (mas ouvi de meus colegas que não é tão boa).
Aqui estão perguntas semelhantes:
fonte
Não funciona até você ligar
no final do seu UncaughtExceptionHandler.
fonte