711 votes

Exemple de AsyncTask Android

Je lisais sur AsyncTask, et j’ai essayé le programme simple ci-dessous. Mais il ne semble pas fonctionner. Comment puis-je le faire fonctionner ?

J’essaie juste de changer l’étiquette après 5 secondes dans le processus d’arrière-plan.

Il s’agit de mon main.xml :

716voto

Graham Smith Points 7963

Ok vous essayez d'accéder à l'interface graphique par un autre thread. Ce, dans la principale, n'est pas une bonne pratique.

L'AsyncTask exécute tout en doInBackground() à l'intérieur d'un autre thread, qui n'ont pas accès à l'interface graphique où votre point de vue.

preExecute() et postExecute() vous offrons l'accès à l'interface graphique avant et après le gros du travail se produit dans ce nouveau fil de discussion, vous pouvez même transmettre le résultat de la longue opération postExecute() pour ensuite afficher tous les résultats du traitement.

Voir ces lignes où, plus tard, vous procurant une TextView:

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

les mettre dans PostExecute()

Vous verrez alors vous TextView texte mise à jour après l' doInBackground complète.

EDIT: j'ai remarqué que votre onClick auditeur ne vérifie pas la Vue qui a été sélectionné. J'ai trouver la meilleure façon de le faire est par l'intermédiaire d'instructions de commutation. J'ai une classe complète édité ci-dessous avec toutes les suggestions afin de sauver la confusion.

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;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button) findViewById(R.id.button1);
        // because we implement OnClickListener we only have to pass "this"
        // (much easier)
        btn.setOnClickListener(this);
    }

    public void onClick(View view) {
        // detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            new LongOperation().execute("");
            break;
        }
    }

    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) {
                    Thread.interrupted();
                }
            }
            return "Executed";
        }

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

        @Override
        protected void onPreExecute() {}

        @Override
        protected void onProgressUpdate(Void... values) {}
    }
}

77voto

bbedward Points 2547

Je suis sûr que c'est une erreur d'exécution, mais vous tentez de changer les éléments d'INTERFACE utilisateur dans le thread d'arrière-plan et qui ne sont pas.

Réviser votre appel et AsyncTask comme suit:

L'Appel De La Classe

Note: personnellement, je suggère à l'aide d' onPostExecute() où vous exécutez votre AsyncTask thread et non dans la classe qui étend la classe AsyncTask lui-même. Je pense que ça rend le code plus facile à lire surtout si vous avez besoin de l'AsyncTask dans plusieurs endroits de la manipulation des résultats légèrement différents.

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

AsyncTask classe:

  @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();
            }
        }
        return "Executed";
  }      

64voto

nitesh Points 1154

Check this out:

J'ai créé un exemple simple pour l'utilisation de AsynTask de Android. Il commence par onPreExceute(), doInBackGround(), publishPrgress() et, enfin, onProgressUpdate().

Dans ce doInBackGround() fonctionne comme un thread d'arrière-plan, tandis que d'autres œuvres dans le Thread de l'INTERFACE utilisateur. Vous ne pouvez pas accéder à un élément d'INTERFACE utilisateur dans doInBackGround(). La séquence est la même que j'ai mentionné.

class TestAsynch extends AsyncTask<Void, Integer, String>
{
    protected void onPreExecute (){
        Log.d("PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d("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){
        Log.d("You are in progress update ... " + a[0]);
    }

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

L'appeler comme cela dans votre activité:

new TestAsynch().execute();

Référence Du Développeur Ici

22voto

Ted Hopp Points 122617

Déplacer ces deux lignes:

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

de votre AsyncTask de l' doInBackground méthode et les mettre dans l' onPostExecute méthode. Votre AsyncTask devrait ressembler à quelque chose comme ceci:

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);
    }
}

11voto

Oded Breiner Points 1852

Plus court exemple pour juste faire quelque chose de manière asynchrone:

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

Pour l'exécuter:

(new MyAsyncTask()).execute();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X