/ / Détails sur l'utilisation de Looper.prepare () dans Android - Android, multithreading, Looper

Spécificités sur l’utilisation de Looper.prepare () dans Android - Android, multithreading, looper

J'ai un peu de mal à comprendre comment utiliser le Looper prepare()/loop()/quit() logique.

J'ai trois threads: l'un est le thread d'interface utilisateur, l'un est un thread de logique de jeu et le dernier est un thread de communication réseau (un thread d'arrière-plan, ne vit que lorsqu'il est utilisé).

Le thread de jeu a de nombreuses dépendances sur les résultats des appels réseau, donc je voulais faire tourner le thread réseau hors du thread de jeu et avoir un Handler poster le résultat.

Bien sûr, puisque le thread d'interface utilisateur n'est pas impliqué, je dois appeler Looper.prepare()... quelque part. Je pensais que cela devrait être appelé dans le fil du jeu, mais je ne peux pas le faire parce que loop() prend le relais.

Comment puis-je publier sur le thread de jeu à partir du thread réseau avec mon gestionnaire?

Réponses:

7 pour la réponse № 1

Ce qui se passe, c'est qu'une fois que vous appelez Looper.prepare () suivi de Looper.loop () sur un thread, tout ce thread déjà faire est de servir son MessageQueue jusqu'à ce que quelqu'un appelle quit () sur son Looper.

L'autre chose à réaliser est que, par défaut, lorsqu'un gestionnaire est instancié, son code s'exécutera toujours sur le thread sur lequel il a été créé.

Ce que vous devez faire est de créer un nouveau thread et dans run (), appelez Looper.prepare (), configurez tous les gestionnaires, puis appelez Looper.loop ().

Garder ces choses à l'esprit ici est le modèle de base que j'utilise beaucoup d'endroits. En outre, il y a de fortes chances que vous utilisiez simplement AsyncTask à la place.

public class NetworkThread extends Thread {
private Handler mHandler;
private Handler mCallback;
private int QUIT = 0;
private int DOWNLOAD_FILE = 1;
public NetworkThread(Handler onDownloaded) {
mCallback = onDownloaded;
}

public void run() {
Looper.prepare();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
// things that this thread should do
case QUIT:
Looper.myLooper().quit();
break;
case DOWNLOAD_FILE:
// download the file
mCallback.sendMessage(/*result is ready*/);
}
}
}
Looper.loop();
}

public void stopWorking() {
// construct message to send to mHandler that causes it to call
// Looper.myLooper().quit
}

public void downloadFile(String url) {
// construct a message to send to mHandler that will cause it to
// download the file
}
}

0 pour la réponse № 2

Pourriez-vous donner quelques exemples de ce que vous utilisez votre thread réseau? Je pense que vous pouvez résoudre vos problèmes sans utiliser Looper.

Vous pouvez utiliser ASyncTask pour effectuer une tâche en arrière-plan qui peut mettre à jour certaines valeurs dans votre thread d'interface utilisateur. Si l'utilisateur doit attendre la fin de l'opération en arrière-plan, vous pouvez afficher ProgressDialog et bloquer l'application dans la méthode OnPreExecute, puis la masquer dans onPostExecute.

Comme je l'ai dit, veuillez décrire davantage vos besoins et votre objectif que vous souhaitez atteindre.