La meilleure utilisation de HandlerThread sur les autres classes comparables
Je suis en train d'essayer de comprendre la meilleure façon d'utiliser HandlerThread
.
Que par définition:
"Pratique de classe pour commencer un nouveau thread qui a un looper. Le looper peut ensuite être utilisé pour créer des classes de gestionnaire. Notez que start() doit toujours être appelé."
J'ai peut-être tort, mais une fonctionnalité similaire, je peux atteindre à l'aide d'un Thread
, Looper
et Handler
. Donc quand dois-je utiliser HandlerThread
? Un exemple serait vraiment utile.
- Je n'ai jamais utilisé HandlerThread, mais peut-être que ce post aidera - stackoverflow.com/questions/7462098/...
- Merci pour la réponse. J'ai vérifié ce post, mais il parle de bénéficier de l'Exécuteur testamentaire plus HandlerThread, dont je suis complètement d'accord. Ma question est plus comme ce est la meilleure façon d'utiliser HandlerThread
- Ce post traite également de cette question. Les exécuteurs sont plus souples et qu'ils peuvent gérer un pool de threads. Plusieurs threads - vous besoin d'utiliser un Exécuteur testamentaire. Seul thread - vous pouvez utiliser un HandlerThread. Pas sûr qu'il importe depuis l'Exécuteur coulc couvrir à la fois les situations. Comme je l'ai compris un HandlerThread permet simplement de créer un gestionnaire sur un thread d'arrière-plan - quelque chose qui peut être fait par d'autres moyens de toute façon.
- Voir mon commentaire ici - stackoverflow.com/questions/17897536/how-to-handle-tcp-data/.... En général, je préfère
HandlerThread
s en raison de la super simple synchronisation viaMessage
s. Cela dit, il peut aussi être un goulot d'étranglement. Aussi, il n'y a rien qui vous empêche d'utiliser un ExecutorService avec HandlerThreads. J'ai écrit auparavant, il n'est pas difficile. - c'était en fait ma question, si on peut faire des choses par d'autres moyens, ce qui est nécessaire pour créer une autre classe. Je suis sûr qu'il ya des avantages dans les scénarios particuliers, dont j'ai besoin de savoir.
- idk si cette affirmation est vraie en général. Il y a beaucoup d'exemples de choses qui peut être fait de plusieurs façons qui n'ont pas nécessairement un avantage évident.
- pouvez-vous veuillez donner un exemple, ou quelque part où je peux trouver un bout de code qui utilise HandlerThread de manière efficace. Les exemples que j'ai vus jusqu'à présent sont juste génériques..merci
- Eu...si c'est le cas, je suis bien..merci
- Voir ma réponse. J'ai dû creuser autour, mais je pense que c'est la distinction que vous cherchez
- Voici un exemple où le système Android utilise un HandlerTread pour la gestion des clics pour les notifications de téléchargements à partir du navigateur: androidxref.com/4.4.2_r2/xref/packages/apps/Browser/src/com/...
- s'il vous plaît pouvez-vous expliquer pourquoi
HandlerThread
peut être un goulot d'étranglement comme vous le dites?
Vous devez vous connecter pour publier un commentaire.
Voici un exemple réel où HandlerThread devient à portée de main. Lorsque vous vous inscrivez pour la Caméra les images de prévisualisation, vous les recevez en
onPreviewFrame()
de rappel. Le la documentation explique que Ce callback n'est appelé sur l'événement de fil ouvert(int) a été appelée à partir de.Habituellement, cela signifie que le callback sera appelé sur-le-main (UI) thread. Ainsi, la tâche de traiter avec l'énorme pixel tableaux peuvent se coincer lorsque les menus sont ouvertes, des animations sont animés, ou même si les statistiques imprimées sur l'écran.
La solution facile est de créer un
new HandlerThread()
et déléguéCamera.open()
à ce fil (je l'ai fait par le biais depost(Runnable)
, vous n'avez pas besoin de mettre en œuvreHandler.Callback
).Noter que tous les autres travaux avec l'Appareil photo peut être fait comme d'habitude, vous n'avez pas à déléguer
Camera.startPreview()
ouCamera.setPreviewCallback()
à la HandlerThread. Pour être sur le côté sécuritaire, je attendre pour leCamera.open(int)
à remplir avant que je continue sur le thread principal (ou ce fil a été utilisé pour appelerCamera.open()
avant le changement).Ainsi, si vous commencez avec le code
d'abord l'extraire comme dans une méthode privée:
et au lieu d'appeler
oldOpenCamera()
simplement utilisernewOpencamera()
:Noter que l'ensemble de la notify() -- wait() communication inter-thread n'est pas nécessaire si vous n'avez pas accès mCamera dans le code d'origine immédiatement après son ouverture.
mise à Jour: Ici, la même approche est appliquée à un accéléromètre: Acclerometer Capteur dans un Thread Séparé
Activity.onPause()
- tout d'abord, parce que c'est le seulement callback que votre activité est assuré de recevoir à partir du système, selon le l'Activité du cycle de vie. Mais il ya des cas où vous pouvez utiliser l'appareil photo après onPause(). Dans de tels cas, vous avez besoin de quelques endroits, d'être gracieux dans différents scénarios.notify()
Camera.open()
peut être douloureusement longue sur certains appareils. La bonne pratique est de ne pas bloquer sur ce, mais de faire tout votre possible initialisations en parallèle, et la configuration de l'aperçu en tant que réponse à un message de la non-thread d'INTERFACE utilisateur. En fait, comme je l'ai mentionné dans le post, c'est très souvent queCamera.open()
est appelé à partir d'un thread d'arrière-plan, par exemple viaAsyncTask
, pour conserver l'INTERFACE utilisateur réactive. L'exemple de code que j'ai posté ici était de résoudre un autre problème: pour afficher une transition sans effort à partir d'un thread unique de mise en œuvre deHandlerThread
sans modification de la logique.getLooper()
sera OK. Voir stackoverflow.com/questions/84285/...; je crois que ce cas particulier (avec une private static de la classe qui encapsule le nouveau thread) est légitime d'exception pour - sinon tout à fait fondé des arguments dans la discussion.getLooper()
méthode des blocs jusqu'à ce que le Looper est instancié dans HandlerThread, donc pour HandlerThread il fonctionne. Mais c'est toujours mauvais modèle pour appeler la méthode start() dans le constructeur.Voici un lien vers le code source pour HandlerThread et Looper.
Si vous regardez les deux, vous verrez que d'un
HandlerThread
est exactement ce qu'il dit c'est une façon pratique pour démarrer uneThread
qui a unLooper
. Pourquoi cela est-il exister? Parce que fils, par défaut n'ont pas de boucle de message. LeHandlerThread
est juste un moyen facile d'en créer un qui ne. Pourriez-vous reproduire cette fonction avecHandler
,Thread
, etLooper
- à en juger par le code source, la réponse est oui.Un
Executor
est différent. UnExecutor
prend soumis tâches exécutables et - devinez quoi-les exécute. Pourquoi est-ce nécessaire? Il vous permet de découpler l'exécution de la tâche à partir de sa substance. Quand souhaitez-vous l'utiliser? Disons que vous avez eu une situation qui exigeait l'exécution de plusieurs tâches en même temps. Vous pourriez choisir, à l'aide d'unExecutor
, à les exécuter sur un seul thread pour qu'elles soient exécutées serialy. Ou vous pouvez utiliser un fixe pool de threads, de sorte que certains, mais pas tous sont exécutés en même temps. Dans les deux cas, la substance de la tâche - c'est à dire de ce qu'est réellement le faire est séparé de la manière dont elle est exécutée.