Exemplo de AsyncTask para Android


680

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>

1
também é possível mostrar o progresso chamando publishprogress () do método doInBackground ().
osum 9/09/12

3

aqui está um exemplo AsyncTask de download de imagem demasiado: android-ios-tutorials.com/182/...
Houcine


3
exemplo simples ... Você deve ler o link
c49 28/02/19

Respostas:


702

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()e postExecute()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 longa postExecute()para mostrar quaisquer resultados do processamento.

Veja estas linhas nas quais você está atualizando posteriormente o seu TextView:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

Colocá-los em onPostExecute().

Você verá o texto do TextView atualizado após a doInBackgroundconclusã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.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity implements OnClickListener {

    Button btn;
    AsyncTask<?, ?, ?> runningTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = findViewById(R.id.button1);

        // Because we implement OnClickListener, we only
        // have to pass "this" (much easier)
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        // Detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            if (runningTask != null)
                runningTask.cancel(true);
            runningTask = new LongOperation();
            runningTask.execute();
            break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Cancel running task(s) to avoid memory leaks
        if (runningTask != null)
            runningTask.cancel(true);
    }

    private final class LongOperation extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // We were cancelled; stop sleeping!
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed"); // txt.setText(result);
            // You might want to change "executed" for the returned string
            // passed into onPostExecute(), but that is up to you
        }
    }
}

2
Não consigo fazer isso <code> btn.setOnClickListener (this); </code> Eclipse fornece um erro ----- "O método setOnClickListener (View.OnClickListener) no tipo View não é aplicável aos argumentos (AsyncTaskActivity)"
Fox

Eu recomendaria alterar a configuração do texto para não ser estático, mas use o argumento do onPostExecute(String result)método Isso tornaria mais claro para os futuros leitores que o argumento é preenchido pelo valor de retorno de doInBackground(String... params).
Eric

@ Eric Tobias - Isso é exatamente o que foi feito na seção comentada. Eu estava acompanhando e respondendo à pergunta dos usuários no meu exemplo completo.
Graham Smith

1
Como adendo e semeador do Google (e vindo de alguém que está aprendendo essas coisas, foi assim que me deparei com isso): a maioria das atualizações de interface do usuário que você faz para algo em que precisa de progresso relatado ao usuário está na chamada de volta emProgressUpdate que é executado no thread principal da interface do usuário.
precisa saber é o seguinte

1
Isto vai certamente atrapalhar se sua atividade é girada ou destruídos por qualquer motivo ...
Sam

792

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.

insira a descrição da imagem aqui


3
paramsé uma matriz. (No exemplo acima, era uma Stringmatriz.) Isso permite passar vários parâmetros do mesmo tipo. Depois, você pode acessar esses parâmetros com params[0], params[1], params[2], etc. No exemplo, havia apenas um único Stringna paramsmatriz. Se você precisar passar vários parâmetros de tipos diferentes (por exemplo, a Stringe an int), consulte esta pergunta .
Suragch 02/02

73

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.

new LongThread() {
    @Override public void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}.execute("");

Classe LongThread (estende o AsyncTask):

@Override
protected String doInBackground(String... params) {
    for (int i = 0; i < 5; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return "Executed";
}      

7
Obrigado por fornecer um exemplo que dissocia o AsyncTask da Atividade
sthomps

1
Sim, finalmente alguém dissocia a tarefa e a atividade. obrigado. E substituir onPostExecutea atividade é brilhante.
Mcy

58

Conceito e código aqui

Eu criei um exemplo simples para usar o AsyncTask do Android. Começa com onPreExecute(), doInBackground(), publishProgress()e finalmente onProgressUpdate().

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 a publishProgresspartir do doInBackgroundqual onProgressUpdateatualizará o widget da interface do usuário.

class TestAsync extends AsyncTask<Void, Integer, String> {
    String TAG = getClass().getSimpleName();

    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG + " PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d(TAG + " DoINBackGround", "On doInBackground...");

        for (int i=0; i<10; i++){
            Integer in = new Integer(i);
            publishProgress(i);
        }
        return "You are at PostExecute";
    }

    protected void onProgressUpdate(Integer...a) {
        super.onProgressUpdate(a);
        Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d(TAG + " onPostExecute", "" + result);
    }
}

Chame assim em sua atividade:

new TestAsync().execute();

Referência do desenvolvedor aqui


3
Aulas começa geralmente com letras maiúsculas em Java, que é uma notação geralmente seguido
Vamsi Pavan Mahesh

20

Mova estas duas linhas:

TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");

fora do doInBackgroundmétodo do seu AsyncTask e coloque-os no onPostExecutemétodo Você AsyncTaskdeve se parecer com isso:

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(5000); // no need for a loop
        } catch (InterruptedException e) {
            Log.e("LongOperation", "Interrupted", e);
            return "Interrupted";
        }
        return "Executed";
    }      

    @Override
    protected void onPostExecute(String result) {               
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}

Ei, o que eu estou executando a tarefa assíncrona no serviço, eu quero retornar algum valor ao thread principal da interface do usuário.
Dipen

@Dipen - Confira esta discussão . Há dois problemas: relatar resultados de um 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.
Ted Hopp

14

Antecedentes / Teoria

O AsyncTask permite executar uma tarefa em um thread em segundo plano, enquanto publica resultados no thread da interface do usuário.

O usuário sempre deve poder interagir com o aplicativo, portanto, é importante evitar o bloqueio do encadeamento principal (UI) com tarefas como o download de conteúdo da Web.

É por isso que usamos um AsyncTask.

Ele oferece uma interface direta, agrupando a fila e o manipulador de mensagens de encadeamento da interface do usuário que permitem enviar e processar objetos e mensagens executáveis ​​de outros encadeamentos .

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.

Nem todos os tipos são sempre usados ​​por uma tarefa assíncrona. Para marcar um tipo como não utilizado, basta usar o tipo Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

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

  • Chamada execute()com parâmetros a serem enviados para a tarefa em segundo plano.

O que acontece

  1. No thread principal / UI , onPreExecute()é chamado.

    • Para inicializar algo neste segmento. (Por exemplo, mostre uma barra de progresso na interface do usuário.)
  2. Em um thread de segundo plano , doInBackground(Params...)é chamado.

    • ( Paramsforam passados ​​por execute.)
    • Onde a tarefa de longa duração deve acontecer.
    • 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.

      • Faz onProgressUpdate()com que seja chamado.
  3. No segmento de segundo plano, um resultado é retornado doInBackground().

    • (Isso dispara o próximo passo.)
  4. No thread principal / UI , onPostExecute()é chamado com o resultado retornado.

Exemplos

Nos dois exemplos, a "tarefa de bloqueio" é um download da Web.

  • O exemplo A baixa uma imagem e a exibe em um ImageView, enquanto
  • O exemplo B baixa alguns arquivos .

Exemplo A

O doInBackground()método baixa a imagem e a armazena em um objeto do tipo BitMap. O onPostExecute()método pega o bitmap e o coloca no ImageView.

class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bitImage;

    public DownloadImageTask(ImageView bitImage) {
        this.bitImage = bitImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mBmp = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mBmp = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mBmp;
    }

    protected void onPostExecute(Bitmap result) {
        bitImage.setImageBitmap(result);
    }
}

Exemplo B

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

Execução do Exemplo B

new DownloadFilesTask().execute(url1, url2, url3);

Muito bom .. Mas continuo recebendo erros sobre conflitos de tipo de retorno - tentando usar o tipo de retorno incompatível. Eu tentei todos os tipos de tipos de retorno, mesmo erro.
9138 John Ktejik #

Olá @johnktejik, convém procurar esse problema específico. Talvez seja isso que está acontecendo com você: o retorno tipo é incompatível com-AsyncTask
TT--

1
Excelente! Considere entrar em edição ?
Peter Mortensen

12

Quando uma tarefa assíncrona é executada, a tarefa passa por quatro etapas:

  1. onPreExecute ()
  2. doInBackground (Params ...)
  3. onProgressUpdate (Progress ...)
  4. onPostExecute (Resultado)

Abaixo está um exemplo de demonstração:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));

            // Escape early if cancel() is called
            if (isCancelled())
                break;
        }
        return totalSize;
    }

    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
 }

E uma vez criada, uma tarefa é executada com muita simplicidade:

new DownloadFilesTask().execute(url1, url2, url3);

execute espera um parâmetro como Runnable. Não aceita string. Qual é o tipo do seu URL? string ou não

10

Exemplo mais curto para fazer algo de forma assíncrona:

class MyAsyncTask extends android.os.AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        // Do something asynchronously
        return null;
    }
}

Para executá-lo:

(new MyAsyncTask()).execute();

10

Como memorizar os parâmetros usados ​​no AsyncTask?

Não

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, Progresse Outputsã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, executa Progresse dá um Output.

Ou seja , AsyncTask<Input, Progress, Output>.

Por exemplo:

Digite a descrição da imagem aqui

Qual é a relação com os métodos?

Entre AsyncTaskedoInBackground()

Digite a descrição da imagem aqui

doInBackground()e onPostExecute(),onProgressUpdate () `também estão relacionados

Digite a descrição da imagem aqui

Como escrever isso no código?

DownloadTask extends AsyncTask<String, Integer, String>{

    // Always same signature
    @Override
    public void onPreExecute()
    {}

    @Override
    public String doInbackGround(String... parameters)
    {
        // Download code
        int downloadPerc = // Calculate that
        publish(downloadPerc);

        return "Download Success";
    }

    @Override
    public void onPostExecute(String result)
    {
        super.onPostExecute(result);
    }

    @Override
    public void onProgressUpdate(Integer... parameters)
    {
        // Show in spinner, and access UI elements
    }

}

Como você irá executar esta tarefa?

new DownLoadTask().execute("Paradise.mp3");

6

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:

public class MyAyncTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute() {
        // Here you can show progress bar or something on the similar lines.
        // Since you are in a UI thread here.
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // After completing execution of given task, control will return here.
        // Hence if you want to populate UI elements with fetched data, do it here.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        // You can track you progress update here
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Here you are in the worker thread and you are not allowed to access UI thread from here.
        // Here you can perform network operations or any heavy operations you want.
        return null;
    }
}

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:

runOnUiThread(new Runnable() {
    textView.setText("something.");
});

or
    yourview.post(new Runnable() {
    yourview.setText("something");
});

Isso ajudará você a conhecer melhor as coisas. Portanto, no seu caso, você precisa definir sua visualização de texto no método onPostExecute ().



3

Tarefa assíncrona de exemplo com solicitação POST:

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();

class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
    String URL;
    List<NameValuePair> parameters;

    private ProgressDialog pDialog;

    public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
    {
        this.URL = url;
        this.parameters = params;
    }

    @Override
    protected void onPreExecute()
    {
        pDialog = new ProgressDialog(LoginActivity.this);
        pDialog.setMessage("Processing Request...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            HttpPost httpPost = new HttpPost(URL);

            if (parameters != null)
            {
                httpPost.setEntity(new UrlEncodedFormEntity(parameters));
            }
            httpResponse = httpClient.execute(httpPost);

            httpEntity = httpResponse.getEntity();
            return EntityUtils.toString(httpEntity);

        }  catch (Exception e)
        {

        }
        return "";
    }

    @Override
    protected void onPostExecute(String result)
    {
        pDialog.dismiss();

        try
        {

        }
        catch (Exception e)
        {

        }
        super.onPostExecute(result);
    }
}


1

Você precisa declarar o botão no listclicklistener. Uma vez clicado, ele chama a classe AsyncTask DownloadJson.

O processo será mostrado abaixo:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DownloadJson().execute();
            }
        });
    }

    // DownloadJSON AsyncTask
    private class DownloadJson extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            newlist = new ArrayList<HashMap<String, String>>();
            json = jsonParser.makeHttpRequest(json, "POST");
            try {
                newarray = new JSONArray(json);
                    for (int i = 0; i < countdisplay; i++) {
                        HashMap<String, String> eachnew = new HashMap<String, String>();
                        newobject = newarray.getJSONObject(i);
                        eachnew.put("id", newobject.getString("ID"));
                        eachnew.put("name", newobject.getString("Name"));
                        newlist.add(eachnew);
                    }
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            newlisttemp.addAll(newlist);
            NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this, newlisttemp);
            newpager.setAdapter(newadapterpager);
        }
    }

1
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Showing progress dialog
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {

        // Do code here

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        // Dismiss the progress dialog
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    @Override
    protected void onCancelled() {

        super.onCancelled();
        progressDialog.dismiss();
        Toast toast = Toast.makeText(
                          getActivity(),
                          "An error is occurred due to some problem",
                          Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();
    }

}


0

Exemplo de exemplo de AsyncTask com progresso

import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn;
    ProgressBar progressBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);
        progressBar = (ProgressBar)findViewById(R.id.pbar);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                new LongOperation().execute("");
                break;
        }
    }

    private class LongOperation extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... params) {
            Log.d("AsyncTask", "doInBackground");
            for (int i = 0; i < 5; i++) {
                try {
                    Log.d("AsyncTask", "task "+(i + 1));
                    publishProgress(i + 1);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            return "Completed";
        }

        @Override
        protected void onPostExecute(String result) {
            Log.d("AsyncTask", "onPostExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText(result);
            progressBar.setProgress(0);
        }

        @Override
        protected void onPreExecute() {
            Log.d("AsyncTask", "onPreExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onPreExecute");
            progressBar.setMax(500);
            progressBar.setProgress(0);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.d("AsyncTask", "onProgressUpdate "+values[0]);
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onProgressUpdate "+values[0]);

            ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
            animation.setDuration(1000);
            animation.setInterpolator(new LinearInterpolator());
            animation.start();
        }
    }
}

0

Tarefa ASync;

public class MainActivity extends AppCompatActivity {

    private String ApiUrl = "your_api";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyTask myTask = new MyTask();
        try {
            String result=myTask.execute(ApiUrl).get();
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
    }

    public class MyTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {

            String result = "";
            HttpURLConnection httpURLConnection = null;
            URL url;

            try {
                url = new URL(strings[0]);
                httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                result = getData(reader);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }

        public String getData(InputStreamReader reader) throws IOException {

            String result = "";
            int data = reader.read();
            while (data!=-1) {
                char now = (char) data;
                result += data;
                data = reader.read();
            }
            return result;
        }
    }

}

Por que a classe está MyTaskdentro da classe MainActivity? Isso é habitual?
Peter Mortensen

0

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:

class MyAsyncTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    tvInfo.setText("Start");
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Your background method
    return null;
  }

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    tvInfo.setText("Finish");
  }
}

E é assim que você chama sua Atividade ou Fragmento:

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();

Re "sobre isso nas próximas lições" : A que isso se refere? Por exemplo, de onde isso é tirado?
Peter Mortensen

0

se você abrir a classe AsyncTask, poderá ver o código abaixo.

public abstract class AsyncTask<Params, Progress, Result> {
    @WorkerThread
    protected abstract Result doInBackground(Params... params);
    @MainThread
    protected void onPreExecute() {
    }
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onPostExecute(Result result) {
    }
}

Recursos do AsyncTask

  1. AsyncTask é classe abstrata
  2. O AsyncTask possui 3 parâmetros genéricos.
  3. AsyncTask possui um método abstrato de doInBackground, onPreExecute, onPostExecute
  4. doInBackground é WorkerThread (você não pode atualizar a interface do usuário)
  5. onPreExecute é MainThread
  6. onPostExecute é MainThread (você pode atualizar a interface do usuário)

exemplo

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    mEmailView = (AutoCompleteTextView) findViewById(R.id.email);

    AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
        @Override
        protected Post doInBackground(Void... params) {
            try {
                ApiClient defaultClient = Configuration.getDefaultApiClient();
                String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
                ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
                Bearer.setApiKey(authorization);
                PostApi apiInstance = new PostApi();
                String id = "1"; // String | id
                Integer commentPage = 1; // Integer | Page number for Comment
                Integer commentPer = 10; // Integer | Per page number For Comment
                Post result;
                try {
                    result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
                } catch (ApiException e) {
                    e.printStackTrace();
                    result = new Post();
                }
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                return new Post();
            }
        }

        @Override
        protected void onPostExecute(Post post) {
            super.onPostExecute(post);
            if (post != null) {
                mEmailView.setText(post.getBody());
                System.out.print(post);
            }
        }
    };
    asyncTask.execute();
}

-1

Altere seu código conforme indicado abaixo:

@Override
protected void onPostExecute(String result) {

    runOnUiThread(new Runnable() {
        public void run() {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
        }
    });
}

1
Você não deve precisar de usar runOnUiThread como OnPostExecute sempre é executado no segmento 1 (não é?)
justdan0227
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.