Estou convertendo meu código de usar Handler
para AsyncTask
. O último é excelente no que faz - atualizações assíncronas e manipulação de resultados no thread principal da interface do usuário. O que não está claro para mim é como lidar com exceções se algo der errado AsyncTask#doInBackground
.
O jeito que eu faço é ter um manipulador de erros e enviar mensagens para ele. Funciona bem, mas é a abordagem "certa" ou existe uma alternativa melhor?
Também entendo que, se eu definir o manipulador de erros como um campo de atividade, ele deverá ser executado no thread da interface do usuário. No entanto, algumas vezes (de forma imprevisível), recebo uma exceção dizendo que o código acionado Handler#handleMessage
está sendo executado no thread errado. Em Activity#onCreate
vez disso, devo inicializar o manipulador de erros ? Colocando runOnUiThread
em Handler#handleMessage
parece redundante, mas ele executa muito confiável.
Respostas:
Eu seguro a
Throwable
ouException
naAsyncTask
própria instância e, em seguida, faço algo com elaonPostExecute()
, para que meu tratamento de erros tenha a opção de exibir uma caixa de diálogo na tela.fonte
AsyncTask
seguinte padrão descrito.Crie um objeto AsyncResult (que você também pode usar em outros projetos)
Retorne esse objeto dos métodos AsyncTask doInBackground e verifique-o no postExecute. (Você pode usar esta classe como uma classe base para suas outras tarefas assíncronas)
Abaixo está uma maquete de uma tarefa que obtém uma resposta JSON do servidor da web.
fonte
super()
emAsyncTaskResult
quando a classe não se estende alguma coisa?Quando sinto a necessidade de lidar com exceções
AsyncTask
corretamente, eu uso isso como super classe:Como de costume, você substitui
doInBackground
sua subclasse para fazer o trabalho em segundo plano, lançando felizes exceções quando necessário. Você é forçado a implementaronPostExecute
(porque é abstrato) e isso lembra-o gentilmente de lidar com todos os tipos deException
que são passados como parâmetro. Na maioria dos casos, as exceções levam a algum tipo de saída da interface do usuário, por issoonPostExecute
é o local perfeito para fazer isso.fonte
params
adiante, para que seja mais parecido com o original e mais fácil migrar?new Task("Param").execute()
mais do que issonew Task().execute("Param")
.Se você quiser usar a estrutura do RoboGuice, que oferece outros benefícios, tente o RoboAsyncTask, que possui um retorno de chamada extra na exceção (). Funciona muito bem e eu uso. http://code.google.com/p/roboguice/wiki/RoboAsyncTask
fonte
RoboGuice
Ainda está vivo? Parece não ter sido atualizado desde 2012?Criei minha própria subclasse AsyncTask com uma interface que define retornos de chamada para obter sucesso e fracasso. Portanto, se uma exceção for lançada no seu AsyncTask, a função onFailure será aprovada na exceção, caso contrário, o retorno de chamada onSuccess será aprovado no resultado. Por que o Android não tem algo melhor disponível está além de mim.
fonte
Uma solução mais abrangente para a solução da Cagatay Kalan é mostrada abaixo:
AsyncTaskResult
ExceptionHandlingAsyncTask
Tarefa de exemplo
fonte
Esta aula simples pode ajudá-lo
fonte
Outra maneira que não depende do compartilhamento variável de membros é usar cancel.
Isto é dos documentos do Android:
Portanto, você pode ligar para cancelar na instrução catch e garantir que onPostExcute nunca seja chamado, mas onCancelled é invocado no thread da interface do usuário. Então você pode mostrar a mensagem de erro.
fonte
cancel(boolean)
resultando em uma chamadaonCancelled()
existente desde o início, masonCancelled(Result)
foi adicionada na API 11 .Na verdade, o AsyncTask usa FutureTask & Executor, o FutureTask suporta a cadeia de exceções Primeiro, vamos definir uma classe auxiliar
Segundo, vamos usar
fonte
Pessoalmente, usarei essa abordagem. Você pode simplesmente capturar as exceções e imprimir o rastreamento da pilha, se precisar das informações.
faça sua tarefa em segundo plano retornar um valor booleano.
É tipo isso:
fonte
Outra possibilidade seria usar
Object
como tipo de retorno eonPostExecute()
verificar o tipo de objeto. É curto.fonte
Se você souber a exceção correta, poderá chamar o
por exemplo:
e vá para "onProgressUpdate" e faça o seguinte
Isso será útil apenas em alguns casos. Além disso, você pode manter uma
Global
Exception
variável e acessar a exceção.fonte