64 votes

ProgressDialog dans AsyncTask

Je suis en train d'essayer d'afficher un ProgressDialog personnalisé pendant le chargement du flux RSS à partir d'un serveur HTTP, j'ai fait une recherche approfondie, mais rien ne m'a aidé à le faire, la seule chose que je sais, c'est que la solution devrait utiliser AsyncTask, mais je suis confus au sujet des paramètres à passer à cette AsyncTask. Voici mon activité :

public class Soirees extends ListActivity {

    private List messages;
    private TextView tvSorties;
    private MyProgressDialog dialog;

    @Override
    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);
        setContentView(R.layout.sorties);

        tvSorties=(TextView)findViewById(R.id.TVTitle);
        tvSorties.setText("Programme des soirées");

        loadFeed();

    }

    private void loadFeed(){

        try{
            BaseFeedParser parser = new BaseFeedParser();
            messages = parser.parse();
            List titles = new ArrayList(messages.size());
            for (Message msg : messages){
                titles.add(msg);
            }
            MessageListAdapter adapter = new MessageListAdapter(this,titles);
            this.setListAdapter(adapter);
            adapter.notifyDataSetChanged();

        } catch (Throwable t){
            Log.e("ImageLoader",t.getMessage(),t);
        }
    }

}

Est-ce que vous pouvez s'il vous plaît m'aider à ajouter AsyncTask à cela?

128voto

Vladimir Ivanov Points 23731

```html

/**
* cette classe effectue tout le travail, affiche la boîte de dialogue avant le travail et la ferme après
*/
public class ProgressTask extends AsyncTask {

public ProgressTask(ListActivity activity) {
this.activity = activity;
dialog = new ProgressDialog(activity);
}

/** boîte de dialogue de progression pour montrer à l'utilisateur que la sauvegarde est en cours de traitement. */
private ProgressDialog dialog;
/** contexte de l'application. */
private ListActivity activity;

protected void onPreExecute() {
this.dialog.setMessage("Début de la progression");
this.dialog.show();
}

    @Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}

MessageListAdapter adapter = new MessageListAdapter(activity, titles);
setListAdapter(adapter);
adapter.notifyDataSetChanged();

if (success) {
Toast.makeText(context, "OK", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Erreur", Toast.LENGTH_LONG).show();
}
}

protected Boolean doInBackground(final String... args) {
try{    
BaseFeedParser parser = new BaseFeedParser();
messages = parser.parse();
List titles = new ArrayList(messages.size());
for (Message msg : messages){
titles.add(msg);
}
activity.setMessages(titles);
return true;
} catch (Exception e)
Log.e("tag", "erreur", e);
return false;
}
}
}

public class Soirees extends ListActivity {
private List messages;
private TextView tvSorties;
private MyProgressDialog dialog;
@Override
public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.sorties);

tvSorties=(TextView)findViewById(R.id.TVTitle);
tvSorties.setText("Programme des soirées");

// appeler simplement ici la tâche
AsyncTask task = new ProgressTask(this).execute();
}

public void setMessages(List msgs) {
messages = msgs;
}

}

```

0 votes

Merci les gars, donc j'essaie ceci, et comme je l'ai demandé, quels paramètres dois-je passer ici ? protégé Boolean doInBackground(final String... args) car la ligne MessageListAdapter adaptateur = new MessageListAdapter(this, titres) lance une erreur

0 votes

L'activité sera suffisante. vous devez simplement définir l'adaptateur de liste.

0 votes

Désolé Vlad, je suis totalement confus :S (cas du débutant)

44voto

Houssem Points 796

Réparé en déplaçant les modificateurs de vue à onPostExecute, donc le code corrigé est :

public class Soirees extends ListActivity {
    private List messages;
    private TextView tvSorties;

    //private MyProgressDialog dialog;
    @Override
    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        setContentView(R.layout.sorties);

        tvSorties=(TextView)findViewById(R.id.TVTitle);
        tvSorties.setText("Programme des soirées");

        new ProgressTask(Soirees.this).execute();

   }

    private class ProgressTask extends AsyncTask {
        private ProgressDialog dialog;
        List titles;
        private ListActivity activity;
        //private List messages;
        public ProgressTask(ListActivity activity) {
            this.activity = activity;
            context = activity;
            dialog = new ProgressDialog(context);
        }

        /** dialog progress pour montrer à l'utilisateur que la sauvegarde est en cours de traitement. */

        /** contexte de l'application. */
        private Context context;

        protected void onPreExecute() {
            this.dialog.setMessage("Début de la progression");
            this.dialog.show();
        }

            @Override
        protected void onPostExecute(final Boolean success) {
                List titles = new ArrayList(messages.size());
                for (Message msg : messages){
                    titles.add(msg);
                }
                MessageListAdapter adapter = new MessageListAdapter(activity, titles);
                activity.setListAdapter(adapter);
                adapter.notifyDataSetChanged();

                if (dialog.isShowing()) {
                dialog.dismiss();
            }

            if (success) {
                Toast.makeText(context, "OK", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "Erreur", Toast.LENGTH_LONG).show();
            }
        }

        protected Boolean doInBackground(final String... args) {
            try{    
                BaseFeedParser parser = new BaseFeedParser();
                messages = parser.parse();

                return true;
             } catch (Exception e){
                Log.e("tag", "erreur", e);
                return false;
             }
          }

    }

}

@Vladimir, merci, votre code a été très utile.

0 votes

Impossible de créer un gestionnaire à l'intérieur d'un thread qui n'a pas appelé Looper.prepare() Je reçois cette erreur. comment résoudre cela.

0 votes

Je pense que vous devez ajouter une autre chose à cela. Vous devez créer un objet privé global pour votre AsyncTask et lorsque l'activité est détruite, vous devez annuler l'AsyncTask. Dans votre cas, si l'utilisateur appuie sur le bouton retour avant que l'AsyncTask ne soit terminé, l'application risque de planter.

0 votes

J'ai essayé d'utiliser une implémentation similaire mais j'obtiens toujours une erreur concernant le fait que l'asynctask n'est pas une activité et que je ne peux donc pas afficher de boîte de dialogue. Est-ce que j'ai oublié quelque chose?

9voto

Praise Song Points 59

AsyncTask est très utile !

class QueryBibleDetail extends AsyncTask{
        private Activity activity;
        private ProgressDialog dialog;
        private Context context;

        public QueryBibleDetail(Activity activity){
            this.activity = activity;
            this.context = activity;
            this.dialog = new ProgressDialog(activity);
            this.dialog.setTitle("Query Bible Detail");
            this.dialog.setMessage("Querying:" + tome + chapterID + ":" + sectionFromID + "-" + sectionToID);
            if(!this.dialog.isShowing()){
                this.dialog.show();
            }
        }

        @Override
        protected String doInBackground(Integer... params) {
            Log.d(TAG,"Querying doInBackground");
            publishProgress(params[0]);

            if(sectionFromID > sectionToID){
                return "";
            }

            String queryBible = "action=query_bible&article="+chapterID+"&id="+tomeID+"&verse_start="+sectionFromID+"&verse_stop="+sectionToID+"";
            try{
                String bible = (Json.getRequest(HOST+queryBible)).trim();
                bible = android.text.Html.fromHtml(bible).toString();
                return bible;
            }catch(Exception e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String bible){
            Log.d(TAG,"Querying onPostExecute");
            TextView bibleBox = (TextView) findViewById(R.id.bibleBox);
            bibleBox.setText(bible);
            this.dialog.dismiss();
        }
    }

3voto

Rohit Singh Points 1934

Ne sais pas quel paramètre utiliser?

Beaucoup de développeurs ont du mal au début à écrire une AsyncTask en raison de l'ambiguïté des paramètres. La principale raison est que nous essayons de mémoriser les paramètres utilisés dans l'AsyncTask. La clé est ne pas mémoriser. Si vous pouvez visualiser ce que votre tâche doit réellement faire, écrire l'AsyncTask avec la signature correcte sera un jeu d'enfant.

Qu'est-ce qu'une AsyncTask?

AsyncTask est une tâche en arrière-plan qui s'exécute dans le thread en arrière-plan. Il prend une Entrée, effectue une progression et donne une Sortie.

c.-à-d. AsyncTask

Déterminez simplement ce que sont vos Entrée, Progression et Sortie et vous serez prêt à partir.

Par exemple

entrer la description de l'image ici

Comment doInBackground() change-t-il avec les paramètres de AsyncTask ?

entrer la description de l'image ici

Comment doInBackground() et onPostExecute(),onProgressUpdate() sont-ils liés ?

entrer la description de l'image ici

Comment pouvez-vous écrire ceci dans un code ?

 DownloadTask extends AsyncTask{

    @Override
    public void onPreExecute(){
    }

    @Override
    public String doInbackGround(String... params)
    {
         // Code de téléchargement
         int pourcentageTelechargement = // calculer cela
         publier(pourcentageTelechargement);

         return "Téléchargement réussi";
    }

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

    @Override
    public void onProgressUpdate(Integer... params)
    {
         // afficher dans le spinner, accéder aux éléments d'interface utilisateur
    }

}

Comment exécuterez-vous cette tâche dans votre activité ?

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

3voto

Yury Points 10837

Il y a quelques jours, j'ai trouvé une très bonne solution à ce problème. Lisez à ce sujet ici. En deux mots, Mike a créé un AsyncTaskManager qui fait le lien entre ProgressDialog et AsyncTask. Il est très facile d'utiliser cette solution. Il vous suffit d'inclure dans votre projet plusieurs interfaces et plusieurs classes et dans votre activité, écrire un code simple et imbriquer votre nouvelle AsyncTask à partir de BaseTask. Je recommande également de lire les commentaires car il y a quelques astuces utiles.

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