Bonjour chers amis développeurs Android ! Aujourd’hui nous allons voir comment fonctionne la classe AsyncTask.
Comme son nom l’indique, une AsyncTask permet de réaliser des tâches de manière asynchrone, à la manière de la classe Thread. L’avantage de l’AsyncTask est sa simplicité d’utilisation et d’implémentation. Le Thread secondaire est créé automatiquement et la communication entre les différents Thread est simplifiée.
Lors du développement d’une application, il faut bien avoir en tête que toutes les tâches consommatrices de ressources (requêtes http, calculs lourds, …) doivent se faire dans un Thread séparé. En effet, le système affiche un message d’erreur et ferme l’application lorsque le Thread principal (appelé UI Thread) est bloqué trop longtemps.
Mise en place du projet
Nous allons donc d’abord créer un nouveau projet appelé AsyncBigCalcul. Nous allons faire en sorte d’effectuer un traitement long de manière asynchrone.
Premièrement, nous allons modifier le layout main.xml en lui ajoutant un Button et une ProgressBar. Le premier servira à lancer le traitement ; la seconde à afficher la progression du traitement.
Voici le code XML, rien de difficile.
?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"
Button
android:layout_marginTop="10dp"
android:id="@+id/btnLaunch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Lancer la tâche" /
TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Progression de la tâche asynchrone:" /
ProgressBar
android:id="@+id/pBAsync"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_margin="10dp"
android:layout_height="wrap_content" /
/LinearLayout
L’activité principale
Nous allons d’abord récupérer les composants définis dans le layout puis ajouter un listener sur le bouton afin qu’à chaque appui on exécute une nouvelle instance de BigCalcul. Jusque là, rien de bien compliqué encore une fois.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
public class AsyncBigCalculActivity extends Activity {
private ProgressBar mProgressBar;
private Button mButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// On récupère les composants de notre layout
mProgressBar = (ProgressBar) findViewById(R.id.pBAsync);
mButton = (Button) findViewById(R.id.btnLaunch);
// On met un Listener sur le bouton
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
BigCalcul calcul=new BigCalcul();
calcul.execute();
}
});
}
}
La classe BigCalcul
Passons ensuite à l’écriture de notre classe BigCalcul, qui hérite d’AsyncTask. Ici je l’ai mise en classe privée mais c’est possible de l’écrire à part. Je vous laisse admirer (et essayer de comprendre) le code :
private class BigCalcul extends AsyncTaskVoid, Integer, Void
{
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(getApplicationContext(), "Début du traitement asynchrone", Toast.LENGTH_LONG).show();
}
@Override
protected void onProgressUpdate(Integer... values){
super.onProgressUpdate(values);
// Mise à jour de la ProgressBar
mProgressBar.setProgress(values[0]);
}
@Override
protected Void doInBackground(Void... arg0) {
int progress;
for (progress=0;progress=100;progress++)
{
for (int i=0; i1000000; i++){}
//la méthode publishProgress met à jour l'interface en invoquant la méthode onProgressUpdate
publishProgress(progress);
progress++;
}
return null;
}
@Override
protected void onPostExecute(Void result) {
Toast.makeText(getApplicationContext(), "Le traitement asynchrone est terminé", Toast.LENGTH_LONG).show();
}
}
Explications :
Les trois paramètres attendus lors de la déclaration sont des types génériques dont voici la signification :
- Le premier est le type des paramètres fournis à la tâche
- Le second est le type de données transmises durant la progression du traitement
- Enfin le troisième est le type du résultat de la tâche
Une AsyncTask doit obligatoirement implémenter la méthode doInBackground. C’est elle qui réalisera le traitement de manière asynchrone dans un Thread séparé. Les méthodes onPreExecute (appelée avant le traitement), onProgressUpdate (appelée lorsque vous souhaitez afficher sa progression) et onPostExecute (appelée après le traitement) sont optionnelles. Un appel à la méthode publishProgress permet la mise à jour de la progression. On ne doit pas appeler la méthode onProgressUpdate directement.
NOTE: Attention, ces trois méthodes (onPreExecute, onProgressUpdate et onPostExecute) s’exécutent depuis l’UI Thread ! C’est d’ailleurs grâce à cela qu’elles peuvent modifier l’interface. On ne doit donc pas y effectuer de traitements lourds.
Ce qui donnera :
Le code me parait assez clair donc je ne détaille pas plus. Vous remarquerez juste que le soi-disant BigCalcul n’est en fait qu’une grosse boucle, ça me paraissait plus lisible.
Voilà, j’espère que les AsyncTask n’ont plus de secret pour vous à présent ! N’hésitez pas à poser des questions si vous avez des difficultés d’implémentation. Le code source de l’exemple est disponible ici.
Aucun commentaire:
Enregistrer un commentaire