Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Du 22 au 24 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. Kotlin
  3. Android : la programmation concurrente
Extrait - Kotlin Les fondamentaux du développement d'applications Android
Extraits du livre
Kotlin Les fondamentaux du développement d'applications Android Revenir à la page d'achat du livre

Android : la programmation concurrente

Présentation

Il est nécessaire d’utiliser la programmation concurrente dans les applications Android afin de n’avoir aucune lenteur au niveau de l’interface graphique. Il est donc nécessaire d’attribuer une tâche entière à la gestion de l’interface graphique et de ses actions rapides et des tâches parallèles dédiés aux traitements longs.

Il existe trois mécanismes permettant de répondre à ce besoin :

  • Le thread : permet de créer une nouvelle tâche ne pouvant communiquer directement avec l’interface graphique.

  • La tâche asynchrone : permet de créer une nouvelle tâche de manière structurée et pouvant communiquer directement avec l’interface graphique.

  • Le handler : permet à plusieurs tâches parallèles de communiquer via un canal commun et standardisé vers l’interface graphique.

Problématique

1. Présentation

Lorsqu’un traitement long doit être exécuté sur une application, celui-ci doit être traité dans un nouveau thread. Effectivement, si un traitement long est exécuté sur le thread gérant l’interface graphique alors elle ne pourra être mise à jour qu’au moment où le traitement sera terminé. Ce qui aura pour effet de rendre l’utilisation de l’application désagréable.

2. Démonstration

Cette démonstration présente une application avec une mauvaise gestion de son traitement long. Lorsque l’on clique sur le bouton "traitement long" l’application se fige pendant 60 secondes.

La démonstration est réalisée dans un nouveau projet dont l’activité principale se nomme MainActivity.

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
   xmlns:app="http://schemas.android.com/apk/res-auto" 
   xmlns:tools="http://schemas.android.com/tools" 
   android:layout_width="match_parent" 
   android:layout_height="match_parent" 
   tools:context="fr.acos.threadwithkotlin.MainActivity"> ...

Les threads

1. Présentation

Les threads permettent d’exécuter plusieurs instructions en même temps. Cela permet d’avoir des instructions qui gèrent l’interface graphique et des instructions qui s’occupent des traitements longs en parallèle dans le principal but de ne pas bloquer l’interface graphique.

2. Syntaxe

Voici la syntaxe du constructeur de la classe Thread :

fun thread( 
    start: Boolean = true,  
    isDaemon: Boolean = false,  
    contextClassLoader: ClassLoader? = null,  
    name: String? = null,  
    priority: Int = -1,  
    block: () -> Unit 
): Thread 

Description des différents paramètres :

Paramètre

Description

start

Si la valeur de ce paramètre est égale à true, alors le thread démarre immédiatement après sa création.

isDaemon

Un daemon thread en Java est un thread qui n’empêche pas la JVM de se terminer.

contextClassLoader

Permet de charger des classes et des ressources dans le thread.

name

Nom du thread.

priority

Priorité du thread.

block

Bloc d’instructions à exécuter dans le thread. C’est le seul paramètre qui est obligatoire.

3. Usage

Exemple de création d’un thread

Thread{traitementLong()}.start() 

Dans cet exemple, un nouveau thread va être créé et lancé pour exécuter le traitement long de la fonction traitementLong().

4. Démonstration

Cette démonstration permet de voir que le traitement long ne bloque pas l’utilisation de l’IHM.

La démonstration est réalisée dans un nouveau projet dont l’activité principale se nomme MainActivity.

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
   xmlns:app="http://schemas.android.com/apk/res-auto" 
   xmlns:tools="http://schemas.android.com/tools" 
   android:layout_width="match_parent" ...

Les tâches asynchrones

1. Présentation

La classe AsyncTask permet de mettre en place des tâches asynchrones. Les tâches asynchrones permettent de faciliter l’utilisation des threads. Pour créer une tâche asynchrone, il est nécessaire de définir une classe héritant de la classe AsyncTask et de redéfinir les fonctions suivantes :

Fonctions

Description

doInBackground()

Cette fonction contient le contenu du traitement long. Les instructions définies dans cette fonction sont exécutées dans un nouveau thread.

onPreExecute()

Cette fonction s’exécute sur le thread UI. Elle s’exécute avant doInBackground().

onPostExecute()

Cette fonction s’exécute sur le thread UI. Elle s’exécute après doInBackground().

onProgressUpdate()

Cette fonction s’exécute sur le thread UI. Elle s’exécute pendant le traitement long donc en même temps que doInBackground(). Cette fonction s’exécute lorsque la fonction publishProgress() est appelée depuis doInBackground().

Pour exécuter la tâche asynchrone, il faut créer une instance de la classe héritant de AsyncTask et utiliser la fonction execute().

2. Démonstration

Cette démonstration permet de voir comment mettre en place des tâches asynchrones.

La démonstration est réalisée dans un nouveau projet dont l’activité principale se nomme MainActivity.

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
   xmlns:app="http://schemas.android.com/apk/res-auto" 
   xmlns:tools="http://schemas.android.com/tools" 
   android:layout_width="match_parent" 
   android:layout_height="match_parent" 
   tools:context="fr.acos.asynctaskwithkotlin.MainActivity"> 
 
   <TextView 
       android:id="@+id/tv_hello" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
     ...

Les Handlers

1. Présentation

Un Handler permet :

  • à différents threads de communiquer entre eux,

  • de réceptionner les messages envoyés par des threads et ensuite d’exécuter une action sur l’IHM par exemple.

La démonstration suivante ne présente pas toutes les possibilités offertes par les handlers.

2. Démonstration

Dans cette démonstration, trois traitements longs vont pouvoir être lancés. Ces traitements longs envoient des messages au handler créé sur le thread UI pour mettre à jour l’IHM. Concrètement, il y a trois diffuseurs de messages et un récepteur de messages.

La démonstration est réalisée dans un nouveau projet dont l’activité principale se nomme MainActivity.

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
   xmlns:app="http://schemas.android.com/apk/res-auto" 
   xmlns:tools="http://schemas.android.com/tools" 
   android:layout_width="match_parent" 
   android:layout_height="match_parent" 
   tools:context="fr.acos.handlerwithkotlin.MainActivity"> 
 
   <TextView 
       android:id="@+id/tv_hello" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="Hello World!" 
       app:layout_constraintBottom_toBottomOf="parent" 
       app:layout_constraintLeft_toLeftOf="parent" 
       app:layout_constraintRight_toRightOf="parent" 
       app:layout_constraintTop_toTopOf="parent" /> 
 
   <Button 
       android:id="@+id/btn_traitement_long1" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:onClick="onClickTraitementLong1" ...

Les coroutines

Kotlin a mis au point un concept de tâches concurrentes coopératives appelé coroutine, permettant de simplifier l’écriture des threads et des tâches asynchrones et d’optimiser la mémoire grâce à un système de fonctions concurrentes suspendues et reprises. Ce concept est encore expérimental aujourd’hui et ne sera pas traité dans le livre.