Eu estava lendo sobre AsyncTask
e tentei o programa simples abaixo. Mas isso não parece funcionar. Como posso fazer isso funcionar?
public class AsyncTaskActivity extends Activity {
Button btn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener((OnClickListener) this);
}
public void onClick(View view){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
return null;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
Estou apenas tentando alterar o rótulo após 5 segundos no processo em segundo plano.
Este é o meu main.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip">
</ProgressBar>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView android:id="@+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace"/>
</LinearLayout>
android
android-asynctask
Raposa
fonte
fonte
Respostas:
Ok, você está tentando acessar a GUI por outro segmento. Isso, em geral, não é uma boa prática.
O AsyncTask executa tudo
doInBackground()
dentro de outro encadeamento, que não tem acesso à GUI onde estão suas visualizações.preExecute()
epostExecute()
ofereça acesso à GUI antes e depois que o trabalho pesado ocorrer neste novo encadeamento, e você pode até passar o resultado da operação longapostExecute()
para mostrar quaisquer resultados do processamento.Veja estas linhas nas quais você está atualizando posteriormente o seu TextView:
Colocá-los em
onPostExecute()
.Você verá o texto do TextView atualizado após a
doInBackground
conclusão.Percebi que o ouvinte do onClick não verifica qual visualização foi selecionada. Acho que a maneira mais fácil de fazer isso é através de instruções do switch. Tenho uma turma completa editada abaixo com todas as sugestões para evitar confusão.
fonte
onPostExecute(String result)
método Isso tornaria mais claro para os futuros leitores que o argumento é preenchido pelo valor de retorno dedoInBackground(String... params)
.Minha resposta completa está aqui , mas aqui está uma imagem explicativa para complementar as outras respostas nesta página. Para mim, entender para onde todas as variáveis estavam indo foi a parte mais confusa do começo.
fonte
params
é uma matriz. (No exemplo acima, era umaString
matriz.) Isso permite passar vários parâmetros do mesmo tipo. Depois, você pode acessar esses parâmetros comparams[0]
,params[1]
,params[2]
, etc. No exemplo, havia apenas um únicoString
naparams
matriz. Se você precisar passar vários parâmetros de tipos diferentes (por exemplo, aString
e anint
), consulte esta pergunta .Tenho certeza de que está sendo executado corretamente, mas você está tentando alterar os elementos da interface do usuário no thread de segundo plano e isso não funciona.
Revise sua chamada e o AsyncTask da seguinte maneira:
Classe de chamada
Nota: Eu pessoalmente sugiro usar
onPostExecute()
onde quer que você execute seu encadeamento AsyncTask e não na classe que estende o próprio AsyncTask. Eu acho que facilita a leitura do código, especialmente se você precisar do AsyncTask em vários locais, lidando com os resultados um pouco diferentes.Classe LongThread (estende o AsyncTask):
fonte
onPostExecute
a atividade é brilhante.Eu criei um exemplo simples para usar o AsyncTask do Android. Começa com
onPreExecute(), doInBackground(), publishProgress()
e finalmenteonProgressUpdate()
.Nesse caso, doInBackground () funciona como um encadeamento em segundo plano, enquanto outros funcionam no thread da interface do usuário. Você não pode acessar um elemento da interface do usuário em doInBackground (). A sequência é a mesma que mencionei.
No entanto, se você precisar atualizar qualquer widget
doInBackground
, poderá chamar apublishProgress
partir dodoInBackground
qualonProgressUpdate
atualizará o widget da interface do usuário.Chame assim em sua atividade:
Referência do desenvolvedor aqui
fonte
Mova estas duas linhas:
fora do
doInBackground
método do seu AsyncTask e coloque-os noonPostExecute
método VocêAsyncTask
deve se parecer com isso:fonte
AsyncTask
, que minha resposta aborda; e enviando um valor de um serviço para o thread da interface do usuário, abordado pela outra discussão. Essas questões são independentes.Antecedentes / Teoria
O AsyncTask permite executar uma tarefa em um thread em segundo plano, enquanto publica resultados no thread da interface do usuário.
Implementação
AsyncTask é uma classe genérica. (São necessários tipos parametrizados em seu construtor.)
Ele usa esses três tipos genéricos:
Params
- o tipo dos parâmetros enviados para a tarefa após a execução.Progress
- o tipo das unidades de progresso publicadas durante a computação em segundo plano.Result
- o tipo do resultado da computação em segundo plano.Esses três parâmetros correspondem a três funções principais nas quais você pode substituir
AsyncTask
:doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Para executar o AsyncTask
execute()
com parâmetros a serem enviados para a tarefa em segundo plano.O que acontece
No thread principal / UI ,
onPreExecute()
é chamado.Em um thread de segundo plano ,
doInBackground(Params...)
é chamado.Params
foram passados porexecute
.)Deve substituir pelo menos o
doInBackground()
AsyncTask.Ligue
publishProgress(Progress...)
para atualizar a interface do usuário com uma exibição do progresso (por exemplo, animação da interface do usuário ou texto do log impresso) enquanto o cálculo em segundo plano ainda estiver em execução.onProgressUpdate()
com que seja chamado.No segmento de segundo plano, um resultado é retornado
doInBackground()
.No thread principal / UI ,
onPostExecute()
é chamado com o resultado retornado.Exemplos
Nos dois exemplos, a "tarefa de bloqueio" é um download da Web.
Exemplo A
O
doInBackground()
método baixa a imagem e a armazena em um objeto do tipo BitMap. OonPostExecute()
método pega o bitmap e o coloca no ImageView.Exemplo B
Execução do Exemplo B
fonte
Quando uma tarefa assíncrona é executada, a tarefa passa por quatro etapas:
Abaixo está um exemplo de demonstração:
E uma vez criada, uma tarefa é executada com muita simplicidade:
fonte
Exemplo mais curto para fazer algo de forma assíncrona:
Para executá-lo:
fonte
Como memorizar os parâmetros usados no AsyncTask?
Se você é novo no AsyncTask, é muito comum ficar confuso ao escrever um AsyncTask. Os principais culpados são os parâmetros usados no AsyncTask, ou seja
AsyncTask<A, B, C>
,. Com base nas assinaturas A, B, C (argumentos) dos métodos, o que torna as coisas ainda mais confusas.Mantenha simples!
A chave é não memorizar . Se você pode visualizar o que sua tarefa realmente precisa fazer, escrever o AsyncTask com a assinatura correta na primeira tentativa seria um pedaço de bolo. Apenas descobrir o que o seu
Input
,Progress
eOutput
são, e você vai ser bom para ir.Então, o que é um AsyncTask?
AsyncTask é uma tarefa em segundo plano que é executada no thread em segundo plano. É preciso um
Input
, executaProgress
e dá umOutput
.Por exemplo:
Qual é a relação com os métodos?
Como escrever isso no código?
Como você irá executar esta tarefa?
fonte
Quando você está no segmento de trabalho, não pode manipular diretamente os elementos da interface do usuário no Android.
Ao usar o AsyncTask, entenda os métodos de retorno de chamada.
Por exemplo:
Para sua informação: Para acessar o thread da interface do usuário a partir de um thread de trabalho, use o método runOnUiThread () ou o método post na sua exibição.
Por exemplo:
Isso ajudará você a conhecer melhor as coisas. Portanto, no seu caso, você precisa definir sua visualização de texto no método onPostExecute ().
fonte
Eu recomendaria facilitar sua vida usando esta biblioteca para trabalhos em segundo plano:
https://github.com/Arasthel/AsyncJobLibrary
É simples assim ...
fonte
Tarefa assíncrona de exemplo com solicitação POST:
fonte
Simplesmente:
fonte
Você precisa declarar o botão no listclicklistener. Uma vez clicado, ele chama a classe AsyncTask DownloadJson.
O processo será mostrado abaixo:
fonte
fonte
Atualização: março 2020
De acordo com a documentação oficial do desenvolvedor do Android , o AsyncTask agora está obsoleto.
Recomenda-se o uso de corelines kotlin . Simplesmente, permite escrever tarefas assíncronas em um estilo seqüencial.
fonte
Exemplo de exemplo de AsyncTask com progresso
fonte
Tarefa ASync;
fonte
MyTask
dentro da classeMainActivity
? Isso é habitual?Ao trabalhar com o AsyncTask, é necessário criar um sucessor de classe e nele registrar a implementação dos métodos necessários para nós. Nesta lição, examinaremos três métodos:
doInBackground - será executado em um novo thread, e aqui resolvemos todas as nossas tarefas difíceis. Como um encadeamento não primário não tem acesso à interface do usuário.
onPreExecute - executado antes do doBackground e tem acesso à interface do usuário
onPostExecute - executado após doInBackground (não funciona se o AsyncTask foi cancelado - sobre isso nas próximas lições) e tem acesso à interface do usuário.
Esta é a classe MyAsyncTask:
E é assim que você chama sua Atividade ou Fragmento:
fonte
se você abrir a classe AsyncTask, poderá ver o código abaixo.
Recursos do AsyncTask
exemplo
fonte
Altere seu código conforme indicado abaixo:
fonte