Estou executando operações remotas de busca de arquivo de áudio e reprodução de arquivo de áudio em um thread de fundo usando AsyncTask
. Uma Cancellable
barra de progresso é mostrada para o tempo de execução da operação de busca.
Quero cancelar / abortar a AsyncTask
execução quando o usuário cancelar (decidir não) a operação. Qual é a forma ideal de lidar com esse caso?
android
android-asynctask
Samuh
fonte
fonte
while(running)
porwhile(!isCancelled())
como outros disseram aqui nos comentários.Se você estiver fazendo cálculos :
isCancelled()
periodicamente.Se você estiver fazendo uma solicitação HTTP :
HttpGet
ou emHttpPost
algum lugar (por exemplo, um campo público).cancel
, liguerequest.abort()
. Isso fará com queIOException
seja jogado dentro do seudoInBackground
.No meu caso, eu tinha uma classe de conector que usei em várias AsyncTasks. Para mantê-lo simples, adicionei um novo
abortAllRequests
método a essa classe e chamei esse método diretamente após a chamadacancel
.fonte
HttpGet.abort()
de um thread de segundo plano ou obterá umandroid.os.NetworkOnMainThreadException
.cancel(true)
interromper a solicitação? Da documentação:If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
HttpURLConnection.disconnect();
cancel(true)
. Eu usei e funciona.O fato é que a chamada de AsyncTask.cancel () chama apenas a função onCancel em sua tarefa. É aqui que você deseja lidar com a solicitação de cancelamento.
Aqui está uma pequena tarefa que uso para acionar um método de atualização
fonte
running
bandeira. AsyncTask tem um sinalizador interno que é definido quando a tarefa é cancelada. Substituawhile (running)
porwhile (!isCancelled())
. developer.android.com/reference/android/os/… Portanto, neste caso simples, você não precisaonCancelled()
substituir.Simples: não use um
AsyncTask
.AsyncTask
foi projetado para operações curtas que terminam rapidamente (dezenas de segundos) e, portanto, não precisam ser canceladas. "Reprodução de arquivo de áudio" não se qualifica. Você nem mesmo precisa de um thread de fundo para a reprodução de arquivos de áudio comuns.fonte
onPostExecute()
para ver se deve prosseguir com o trabalho.A única maneira de fazer isso é verificando o valor do método isCancelled () e parando a reprodução quando ele retornar true.
fonte
É assim que escrevo minha AsyncTask,
o ponto-chave é adicionar Thread.sleep (1);
fonte
Nossa variável de classe AsyncTask global
E a ação KEYCODE_BACK que interrompe AsyncTask
Funciona para mim.
fonte
Não gosto de forçar a interrupção de minhas tarefas assíncronas
cancel(true)
desnecessariamente porque podem ter recursos a serem liberados, como fechar soquetes ou fluxos de arquivos, gravar dados no banco de dados local etc. Por outro lado, enfrentei situações em que o a tarefa assíncrona se recusa a terminar sozinha parte do tempo, por exemplo, às vezes quando a atividade principal está sendo fechada e eu solicito que a tarefa assíncrona termine de dentro doonPause()
método da atividade . Portanto, não é uma questão de simplesmente ligarrunning = false
. Tenho que buscar uma solução mista: ambos ligamrunning = false
, depois dão à tarefa assíncrona alguns milissegundos para terminar e, em seguida, chamamcancel(false)
oucancel(true)
.Como resultado colateral, depois de
doInBackground()
terminar, às vezes oonCancelled()
método é chamado e às vezesonPostExecute()
. Mas pelo menos o encerramento da tarefa assíncrona é garantido.fonte
Com referência à resposta de Yanchenko em 29 de abril de '10: Usar uma abordagem 'while (running)' é legal quando seu código em 'doInBackground' precisa ser executado várias vezes durante cada execução da AsyncTask. Se o seu código em 'doInBackground' tiver que ser executado apenas uma vez por execução da AsyncTask, envolver todo o seu código em 'doInBackground' em um loop 'while (running)' não interromperá a execução do código de segundo plano (thread de segundo plano) quando o A própria AsyncTask é cancelada, porque a condição 'while (running)' só será avaliada depois que todo o código dentro do loop while tiver sido executado pelo menos uma vez. Você deve então (a.) Dividir seu código em 'doInBackground' em vários blocos 'while (running)' ou (b.) Executar vários 'isCancelled'https://developer.android.com/reference/android/os/AsyncTask.html .
Para a opção (a.), Pode-se modificar a resposta de Yanchenko da seguinte forma:
Para a opção (b.), Seu código em 'doInBackground' será semelhante a este:
fonte