C'est a tel point important qu'une tentative de lancement d'un socket sur le thread principal provoquera l'exception NetworkOnMainThreadException.
Handler et Runnable
Il faut savoir que l'utilisation de la méthode Handler.post() ne crée pas de nouveau thread en arrière plan. Ce qui signifie qu'on ne peut pas utiliser de Handler pour lancer un service d'écoute réseau par exemple.
Handler handler = new Handler(); final Runnable r = new Runnable() { public void run() { tv.append("Serveur d'écoute activé"); // ... Lancement du socket d'écoute ici... } }; handler.post(r);
Avec ce code, donc, point de salut. Même si c'est beau et facile, ça ne marchera pas. Le lancement du socket provoquera une exception NetworkOnMainThreadException. Car si vous utilisez un Handler, votre Runnable sera juste placé dans la file des messages et sera exécuté dès que possible sur le thread dans lequel il se trouve (probablement le thread principal).
Classe AsyncTask
La solution la plus généralement encouragée est celle de l'emploi de la classe AsyncTask, qui est vraiment lancée dans un nouveau thread. Elle permet également de suivre l'évolution de la tâche ainsi que de récupérer facilement le résultat de l'opération. Il faudra simplement créer une nouvelle classe qui héritera de AsyncTask (extends). Quelques règles doivent toutefois être respectées :- La classe AsyncTask doit impérativement être chargée sur le UI Thread
- L'instance de la tâche doit être créée sur le UI Thread
- la méthode execute(Params...) doit être invoquée sur le UI Thread
- Ne pas exécuter manuellement onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
- La tâche ne peut être exécutée qu'une seule fois. Si on tente de l'exécuter une seconde fois, une exception sera lancée.
Ce qu'on peut retenir
- La classe Runnable permet juste de préparer un bout de programme qu'on souhaite exécuter plus tard.
- Si on lance un Runnable avec un Handler, le Runnable sera exécuté sur le thread en court. On pourra utiliser cette méthode pour réaliser un 'timer', mais attention que le traitement ne soit pas trop long si vous êtes sur le UI Thread !
- Si on lance un Runnable avec un Thread... le Runnable sera exécuté sur le nouveau thread.
- La classe AsyncTask permet de réaliser un traitement en arrière-plan, dans un nouveau thread.
Aucun commentaire:
Enregistrer un commentaire