AXOPEN

Android: Qu’est ce qu’une AsyncTask ?

Qu’est-ce qu’une AsyncTask?

Les AsyncTask permettent une utilisation correcte et facile du ThreadUI. Cette classe permet d’effectuer des tâches de fond et de publier des résultats sans manipuler des threads et/ou des handlers.

Une tâche asynchrone est définie par un calcul qui fonctionne sur un thread en arrière-plan et dont le résultat est publié sur le ThreadUI. Une tâche asynchrone est définie par 3 types génériques, appelés : le paramètre, la progression et le résultat ainsi que 4 étapes, appelées OnPreExecute, doInBackground, onProgressUpdate et onPostExecute.

Idéalement, les AsyncTasks sont utilisées pour des utilisations courtes (quelques secondes au plus). Pour des opérations de longues périodes, il est fortement recommandé d’utiliser les différentes API comme Executor, ThreadPoolExecutor et FutureTask.

Utilisation d’une AsyncTask

AsyncTask est une classe abstraite. Pour l’utiliser, il faut donc créer une classe qui en hérite.

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

Une fois créée, une tâche est exécutée très simplement:

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

De cette manière, les tâches sont mises dans une file d’attente et s’exécuteront les unes après les autres.

Pour quelles s’exécutent parallèlement :

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

 

Les types génériques d’AsyncTask

Les trois types utilisés par une tâche asynchrone sont les suivants:

  1. Params, le type des paramètres envoyés à la tâche lors de l’exécution.
  2. Progrès, le type des unités d’étape publiées lors du calcul de fond.
  3. Par conséquent, le type de résultat du calcul en arrière-plan.

Tous les types ne sont pas toujours utilisés par une tâche asynchrone. Pour marquer un type non utilisé, il suffit d’utiliser le type Void:

class MaTache extends AsyncTask<Void, Void, Void> { ... }

 

Le cycle de vie de l’AsyncTask

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

  1. OnPreExecute (), appelé sur le thread d’interface avant que la tâche soit exécutée. Cette étape est normalement utilisée pour configurer la tâche, par exemple, en montrant une barre de progression dans l’interface utilisateur.
  2. doInBackground (Param …), invoqué sur le thread en arrière-plan immédiatement après OnPreExecute (). Cette étape est utilisée pour effectuer le calcul de fond qui peut prendre un certain temps. Les paramètres de la tâche asynchrone sont passés à cette étape. Le résultat du calcul doit être retourné par cette étape et sera renvoyé à la dernière étape. Cette étape peut également utiliser publishProgress (Progress …) de publier une ou plusieurs unités de progression. Ces valeurs sont publiées sur le thread d’interface utilisateur, à l’étape onProgressUpdate (Progress …).
  3. onProgressUpdate (Progress …), invoqué sur le thread d’interface utilisateur après un appel à publishProgress (Progress …). Le moment de l’exécution est indéfini. Cette méthode est utilisée pour afficher toute forme de progression dans l’interface utilisateur tandis que le calcul de fond est toujours en cours d’exécution. Par exemple, il peut être utilisé pour animer une barre de progression ou afficher des logs.
  4. onPostExecute (Résultat), appelé sur le thread UI après la fin du calcul. Le résultat est transmis à cette étape en tant que paramètre.

 

Règles d’une AsyncTask

Pour que cette classe fonctionne correctement, il y a quelques règles à respecter :

  • La classe AsyncTask doit être chargée sur le thread UI. Ceci est fait automatiquement dès JELLY_BEAN (API 16, 17, 18).
  • L’instance de la tâche doit être créée sur le thread UI.
  • execute(Param …) doit être invoqué sur le thread UI.
  • Ne pas appeler OnPreExecute (), onPostExecute (Résultat), doInBackground(Param …), onProgressUpdate (Progress …) manuellement.
  • La tâche ne peut être exécutée qu’une seule fois (une exception sera levée si une deuxième exécution est tentée).