Na minha Atividade, uso uma classe que se estende de AsyncTask e um parâmetro que é uma instância desse AsyncTask. Quando ligo mInstanceOfAT.execute("")
está tudo bem. Mas o aplicativo falha quando pressiono um botão de atualização que chama novamente o AsyncTask (caso o trabalho de rede não funcione). A causa aparece então uma exceção que diz
Não é possível executar a tarefa: a tarefa já foi executada (uma tarefa pode ser executada apenas uma vez)
Tentei chamar cancel (true) para a instância do Asyctask, mas também não funciona. Até agora, a única solução é criar novas instâncias do Asyntask. Essa é a maneira correta?
Obrigado.
fonte
As razões para instâncias de disparar e esquecer do ASyncTask são bem detalhadas na resposta de Steve Prentice - No entanto, embora você esteja restrito a quantas vezes você executa um ASyncTask, você é livre para fazer o que quiser enquanto o thread estiver em execução. .
Coloque seu código executável dentro de um loop em doInBackground () e use um bloqueio simultâneo para acionar cada execução. Você pode recuperar os resultados usando publishProgress () / onProgressUpdate () .
Exemplo:
Obviamente, isso é um pouco mais complicado do que o uso tradicional do ASyncTask, e você desiste do uso de publishProgress () para relatórios de progresso reais. Mas se a sua preocupação é a memória, essa abordagem garantirá que apenas um ASyncTask permaneça na pilha no tempo de execução.
fonte
IllegalMonitorStateException
emrunAgain
(chamado poronProgressUpdate
) ver esta resposta: stackoverflow.com/a/42646476/2711811 . Sugere (e funcionou para mim) que assignal()
necessidades precisam ser cercadas por umlock
/unlock
. Isso pode ter a ver com o tempo dapublishProgress
chamadaonProgressUpdate
.Eu tive o mesmo problema. No meu caso, tenho uma tarefa que quero fazer dentro
onCreate()
e dentroonResume(
). Então, fiz o meu Asynctask estático e obtive a instância dele. Agora ainda temos o mesmo problema.Então, o que eu fiz no onPostExecute () é o seguinte:
Tendo em mente que eu verifico no método estático getInstance que minha instância não é nula; caso contrário, eu a crio:
O método em postExecute esvaziará a instância e a recriará. Claro que isso pode ser feito fora da sala de aula.
fonte
Tornei minhas tarefas de rotação estáticas, o que me ajudou a anexar, desanexar e anexá-las novamente aos threads da interface do usuário nas alterações de rotação. Mas, voltando à sua pergunta, o que faço é criar um sinalizador para ver se o encadeamento está em execução. Quando você deseja reiniciar o encadeamento, verifico se a tarefa de rotação está sendo executada, se é para fazer um aviso. Caso contrário, eu o anulo e, em seguida, crio um novo, que contornará o erro que você está vendo. Além disso, após a conclusão bem-sucedida, anulo a tarefa de reconhecimento de rotação concluída, para que ela esteja pronta para continuar novamente.
fonte
Sim, é verdade, o documento diz que apenas pode ser executado um Asyntask.
Toda vez que você precisar usá-lo, você deve ter uma instância:
fonte