Exemple d'AsyncTask Android


680

Je lisais AsyncTasket j'ai essayé le programme simple ci-dessous. Mais cela ne semble pas fonctionner. Comment puis-je le faire fonctionner?

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

J'essaie juste de changer l'étiquette après 5 secondes en arrière-plan.

Voici mon 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
vous pouvez également afficher la progression en appelant publishprogress () à partir de la méthode doInBackground ().
osum


voici un exemple asynctask de téléchargement d'image aussi: android-ios-tutorials.com/182/…
Houcine


3
exemple simple ... Vous devez lire le lien
c49

Réponses:


702

Ok, vous essayez d'accéder à l'interface graphique via un autre thread. Ceci, dans l'ensemble, n'est pas une bonne pratique.

L'AsyncTask exécute tout à l' doInBackground()intérieur d'un autre thread, qui n'a pas accès à l'interface graphique où se trouvent vos vues.

preExecute()et postExecute()vous offre un accès à l'interface graphique avant et après le levage de charges lourdes dans ce nouveau thread, et vous pouvez même transmettre le résultat de la longue opération à postExecute()pour afficher ensuite les résultats du traitement.

Voir ces lignes où vous mettez ultérieurement à jour votre TextView:

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

Mettez-les onPostExecute().

Vous verrez alors votre texte TextView mis à jour après la doInBackgroundfin.

J'ai remarqué que votre écouteur onClick ne vérifie pas quelle vue a été sélectionnée. Je trouve que la façon la plus simple de le faire est via les instructions switch. J'ai un cours complet édité ci-dessous avec toutes les suggestions pour éviter 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;
    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
Je ne peux pas faire ceci <code> btn.setOnClickListener (this); </code> Eclipse donne une erreur ----- "La méthode setOnClickListener (View.OnClickListener) dans le type View n'est pas applicable pour les arguments (AsyncTaskActivity)"
Fox

Je conseillerais de changer le réglage du texte pour qu'il ne soit pas statique mais de prendre l'argument de la onPostExecute(String result)méthode. Il serait plus clair pour les futurs lecteurs que l'argument est rempli par la valeur de retour de doInBackground(String... params).
Eric

@Eric Tobias - Que les choses exactes ont déjà été faites dans la section commentée. Je suivais et répondais à la question des utilisateurs dans mon exemple complet.
Graham Smith

1
En tant qu'addenda et google seeder (et provenant de quelqu'un qui apprend actuellement ce genre de choses, c'est ainsi que je suis tombé sur ce sujet): la majorité des mises à jour de l'interface utilisateur que vous ferez pour quelque chose dont vous avez besoin de rapporter les progrès à l'utilisateur est dans le rappel de ProgressUpdate qui est exécuté dans le thread d'interface utilisateur principal.
RichieHH

1
Cela gâchera sûrement si votre activité est tournée ou détruite pour une raison quelconque ...
Sam

792

Ma réponse complète est ici , mais voici une image explicative pour compléter les autres réponses sur cette page. Pour moi, comprendre où allaient toutes les variables était la partie la plus déroutante au début.

entrez la description de l'image ici


3
paramsest un tableau. (Dans l'exemple ci-dessus, c'était un Stringtableau.) Cela vous permet de passer plusieurs paramètres du même type. Ensuite , vous pouvez accéder à ces paramètres avec params[0], params[1], params[2], etc. Dans l'exemple, il n'y avait qu'un seul Stringdans le paramstableau. Si vous devez transmettre plusieurs paramètres de différents types (par exemple, a Stringet an int), consultez cette question .
Suragch

73

Je suis sûr qu'il s'exécute correctement, mais vous essayez de modifier les éléments d'interface utilisateur dans le thread d'arrière-plan et cela ne fonctionnera pas.

Modifiez votre appel et AsyncTask comme suit:

Classe d'appel

Remarque: Je suggère personnellement d'utiliser onPostExecute()partout où vous exécutez votre thread AsyncTask et non dans la classe qui étend AsyncTask elle-même. Je pense que cela rend le code plus facile à lire, surtout si vous avez besoin de AsyncTask à plusieurs endroits pour gérer les 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("");

Classe LongThread (étend 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
Merci d'avoir fourni un exemple qui dissocie la tâche AsyncTask de l'activité
sthomps

1
oui, enfin quelqu'un dissocie la tâche et l'activité. merci. Et le dépassement onPostExecutede l'activité est génial.
mcy

58

Concept et code ici

J'ai créé un exemple simple d'utilisation d'AsyncTask d'Android. Cela commence par onPreExecute(), doInBackground(), publishProgress()et enfin onProgressUpdate().

En cela, doInBackground () fonctionne comme un thread d'arrière-plan, tandis que d'autres fonctionnent dans le thread d'interface utilisateur. Vous ne pouvez pas accéder à un élément d'interface utilisateur dans doInBackground (). La séquence est la même que celle que j'ai mentionnée.

Cependant, si vous devez mettre à jour un widget à partir de doInBackground, vous pouvez appeler à publishProgresspartir doInBackgroundduquel mettre onProgressUpdateà jour votre widget UI.

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

Appelez ça comme ça dans votre activité:

new TestAsync().execute();

Référence développeur ici


3
les cours commencent par des lettres majuscules généralement en Java, c'est une notation habituellement suivie
Vamsi Pavan Mahesh

20

Déplacez ces deux lignes:

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

hors de la doInBackgroundméthode de votre AsyncTask et les mettre dans la onPostExecuteméthode. Votre AsyncTaskdevrait ressembler à 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);
    }
}

Hé, ce que j'exécute une tâche asynchrone sur le service, je veux retourner une valeur au thread principal de l'interface utilisateur.
Dipen

@Dipen - Découvrez cette discussion . Il y a deux problèmes: rapporter les résultats d'un AsyncTask, auquel ma réponse répond; et l'envoi d'une valeur d'un service au thread d'interface utilisateur, que l'autre discussion aborde. Ces problèmes sont indépendants.
Ted Hopp

14

Contexte / Théorie

AsyncTask vous permet d'exécuter une tâche sur un thread d'arrière-plan, tout en publiant les résultats sur le thread d'interface utilisateur.

L'utilisateur doit toujours pouvoir interagir avec l'application, il est donc important d'éviter de bloquer le thread principal (UI) avec des tâches telles que le téléchargement de contenu à partir du Web.

C'est pourquoi nous utilisons un AsyncTask.

Il offre une interface simple en encapsulant la file d'attente de messages de threads d'interface utilisateur et le gestionnaire qui vous permettent d'envoyer et de traiter des objets exécutables et des messages à partir d'autres threads .

la mise en oeuvre

AsyncTask est une classe générique. (Il prend des types paramétrés dans son constructeur.)

Il utilise ces trois types génériques:

Params - le type des paramètres envoyés à la tâche lors de l'exécution.

Progress - le type des unités de progression publiées lors du calcul en arrière-plan.

Result - le type du résultat du calcul d'arrière-plan.

Tous les types ne sont pas toujours utilisés par une tâche asynchrone. Pour marquer un type comme inutilisé, utilisez simplement le type Void:

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

Ces trois paramètres correspondent à trois fonctions principales dans lesquelles vous pouvez remplacer AsyncTask:

  • doInBackground(Params...)
  • onProgressUpdate(Progress...)
  • onPostExecute(Result)

Pour exécuter AsyncTask

  • Appel execute()avec paramètres à envoyer à la tâche en arrière-plan.

Ce qui se produit

  1. Sur le thread principal / UI , onPreExecute()est appelé.

    • Pour initialiser quelque chose dans ce fil. (Par exemple, afficher une barre de progression sur l'interface utilisateur.)
  2. Sur un fil d'arrière - plan , doInBackground(Params...)est appelé.

    • ( Paramsont été passés via execute.)
    • Où la tâche de longue haleine devrait se produire.
    • Doit remplacer au moins doInBackground()pour utiliser AsyncTask.

    • Appelez publishProgress(Progress...)pour mettre à jour l'interface utilisateur avec un affichage de la progression (par exemple, animation de l'interface utilisateur ou texte du journal imprimé) pendant que le calcul en arrière-plan est toujours en cours d'exécution.

      • Fait onProgressUpdate()appeler.
  3. Sur le thread d'arrière - plan, un résultat est renvoyé par doInBackground().

    • (Cela déclenche l'étape suivante.)
  4. Sur le thread principal / UI , onPostExecute()est appelé avec le résultat renvoyé.

Exemples

Dans les deux exemples, la «tâche de blocage» est un téléchargement à partir du Web.

  • L'exemple A télécharge une image et l'affiche dans une ImageView, tandis que
  • L'exemple B télécharge certains fichiers .

Exemple A

La doInBackground()méthode télécharge l'image et la stocke dans un objet de type BitMap. La onPostExecute()méthode prend le bitmap et le place dans 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);
    }
}

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

Exemple d'exécution B

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

Très bien .. Mais je reçois toujours des erreurs sur les conflits de type de retour - en essayant d'utiliser un type de retour incompatible. J'ai essayé toutes sortes de types de retours, même erreur.
John Ktejik

Salut @johnktejik, vous voudrez peut-être rechercher ce problème spécifique. C'est peut-être ce qui vous arrive: le-type-de-retour-est-incompatible-avec-asynctask
TT--

1
Excellent! Pensez à vous lancer dans l' édition ?
Peter Mortensen

12

Lorsqu'une tâche asynchrone est exécutée, la tâche passe par quatre étapes:

  1. onPreExecute ()
  2. doInBackground (Params ...)
  3. onProgressUpdate (Progress ...)
  4. onPostExecute (Résultat)

Voici un exemple de démonstration:

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

Et une fois que vous avez créé, une tâche est exécutée très simplement:

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

execute attend un paramètre comme Runnable. Il n'accepte pas de chaîne. Quel est le type de votre URL? string or not

10

Exemple le plus court pour faire simplement 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();

10

Comment mémoriser les paramètres utilisés dans AsyncTask?

Ne le fais pas

Si vous êtes nouveau dans AsyncTask, il est très courant de se tromper lors de l'écriture d'une AsyncTask. Les principaux coupables sont les paramètres utilisés dans la tâche AsyncTask, c'est-à-dire AsyncTask<A, B, C>. Sur la base des A, B, C (arguments) signature des méthodes, ce qui rend les choses encore plus confuses.

Rester simple!

La clé est de ne pas mémoriser . Si vous pouvez visualiser ce que votre tâche doit vraiment faire, écrire la tâche AsyncTask avec la signature correcte à la première tentative serait un jeu d'enfant. Il suffit de comprendre ce que votre Input, Progresset Outputsont, et vous serez bon d'aller.

Qu'est-ce qu'une AsyncTask?

AsyncTask est une tâche d'arrière-plan qui s'exécute dans le thread d'arrière-plan. Il prend un Input, effectue Progresset donne un Output.

-À- dire , AsyncTask<Input, Progress, Output>.

Par exemple:

Entrez la description de l'image ici

Quelle est la relation avec les méthodes?

Entre AsyncTasketdoInBackground()

Entrez la description de l'image ici

doInBackground()et onPostExecute(),onProgressUpdate () `sont également liés

Entrez la description de l'image ici

Comment écrire cela dans le code?

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
    }

}

Comment allez-vous exécuter cette tâche?

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

6

Lorsque vous êtes dans le thread de travail, vous ne pouvez pas manipuler directement les éléments de l'interface utilisateur sur Android.

Lorsque vous utilisez AsyncTask, veuillez comprendre les méthodes de rappel.

Par exemple:

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

Pour info: pour accéder au thread d'interface utilisateur à partir d'un thread de travail, vous utilisez la méthode runOnUiThread () ou la méthode de publication dans votre vue.

Par exemple:

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

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

Cela vous aidera à mieux connaître les choses. Par conséquent, dans votre cas, vous devez définir votre affichage de texte dans la méthode onPostExecute ().


5

Je recommanderais de vous faciliter la vie en utilisant cette bibliothèque pour les travaux d'arrière-plan:

https://github.com/Arasthel/AsyncJobLibrary

C'est aussi simple que ça ...

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {

    @Override
    public void doOnBackground() {
        startRecording();
    }
});

3

Exemple de tâche asynchrone avec demande 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

Vous devez déclarer le bouton surclicklistener. Une fois cliqué, il appelle la classe AsyncTask DownloadJson.

Le processus sera indiqué ci-dessous:

@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

Exemple d'exemple AsyncTask avec progression

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

Tâche 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;
        }
    }

}

Pourquoi la classe est-elle à l' MyTaskintérieur de la classe MainActivity? Est-ce habituel?
Peter Mortensen

0

En travaillant avec AsyncTask, il est nécessaire de créer un successeur de classe et d'enregistrer la mise en œuvre des méthodes nécessaires pour nous. Dans cette leçon, nous examinerons trois méthodes:

doInBackground - sera exécuté dans un nouveau thread, et ici nous résolvons toutes nos tâches difficiles. Parce qu'un thread non principal n'a pas accès à l'interface utilisateur.

onPreExecute - exécuté avant doInBackground et a accès à l'interface utilisateur

onPostExecute - exécuté après doInBackground (ne fonctionne pas si AsyncTask a été annulé - à ce sujet dans les prochaines leçons) et a accès à l'interface utilisateur.

Voici la 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");
  }
}

Et voici comment appeler votre activité ou fragment:

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

Concernant "à ce sujet dans les prochaines leçons" : à quoi cela fait-il référence? Par exemple, d'où cela vient-il?
Peter Mortensen

0

si vous ouvrez la classe AsyncTask, vous pouvez voir le code ci-dessous.

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

Fonctionnalités AsyncTask

  1. AsyncTask est une classe abstraite
  2. AsyncTask a 3 paramètres génériques.
  3. AsyncTask a une méthode abstraite de doInBackground, onPreExecute, onPostExecute
  4. doInBackground est WorkerThread (vous ne pouvez pas mettre à jour l'interface utilisateur)
  5. onPreExecute est MainThread
  6. onPostExecute est MainThread (vous pouvez mettre à jour l'interface utilisateur)

exemple

@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

Modifiez votre code comme indiqué ci-dessous:

@Override
protected void onPostExecute(String result) {

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

1
Vous ne devriez pas avoir besoin d'utiliser runOnUiThread car onPostExecute s'exécute toujours sur le thread 1 (n'est-ce pas?)
justdan0227
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.