J'écris ma première application Android et j'essaie de comprendre la communication entre les services et les activités. J'ai un service qui fonctionnera en arrière-plan et effectuera une connexion GPS et basée sur le temps. J'aurai une activité qui sera utilisée pour démarrer et arrêter le service.
Donc, tout d'abord, je dois être en mesure de déterminer si le service est en cours d'exécution au démarrage de l'activité. Il y a d'autres questions ici à ce sujet, donc je pense que je peux comprendre cela (mais n'hésitez pas à offrir des conseils).
Mon vrai problème: si l'activité est en cours d'exécution et que le service est démarré, j'ai besoin d'un moyen pour le service d'envoyer des messages à l'activité. Chaînes simples et entiers à ce stade - messages d'état principalement. Les messages ne se produiront pas régulièrement, donc je ne pense pas que l'interrogation du service soit une bonne façon de procéder s'il existe une autre solution. Je veux cette communication uniquement lorsque l'activité a été démarrée par l'utilisateur - je ne veux pas démarrer l'activité à partir du service. En d'autres termes, si vous démarrez l'activité et que le service est en cours d'exécution, vous verrez des messages d'état dans l'interface utilisateur d'activité lorsque quelque chose d'intéressant se produit. Si vous ne démarrez pas l'activité, vous ne verrez pas ces messages (ils ne sont pas si intéressants).
Il semble que je devrais être en mesure de déterminer si le service est en cours d'exécution et, dans l'affirmative, d'ajouter l'activité en tant qu'écouteur. Supprimez ensuite l'activité en tant qu'auditeur lorsque l'activité s'arrête ou s'arrête. Est-ce vraiment possible? La seule façon pour moi de le faire est de demander à Activity d'implémenter Parcelable et de créer un fichier AIDL afin que je puisse le passer via l'interface distante du Service. Cela semble cependant exagéré, et je n'ai aucune idée de la façon dont l'activité devrait implémenter writeToParcel () / readFromParcel ().
Existe-t-il un moyen plus simple ou meilleur? Merci pour toute aide.
ÉDITER:
Pour ceux qui sont intéressés par cela plus tard, il existe un exemple de code de Google pour gérer cela via AIDL dans le répertoire d'exemples: /apis/app/RemoteService.java
la source
busy-wait
l'activité? Pouvez-vous expliquer s'il vous plaît?Activity.onCreate()
?Intents
en envoyant des données via desParcellable
messages entre eux?Le demandeur est probablement passé depuis longtemps, mais au cas où quelqu'un d'autre le chercherait ...
Il y a une autre façon de gérer cela, qui je pense pourrait être la plus simple.
Ajoutez un
BroadcastReceiver
à votre activité. Enregistrez-le pour recevoir une intention personnaliséeonResume
et annulez-leonPause
. Envoyez ensuite cette intention à partir de votre service lorsque vous souhaitez envoyer vos mises à jour de statut ou ce que vous avez.Assurez-vous que vous ne seriez pas mécontent si une autre application écoutait votre
Intent
(quelqu'un pourrait-il faire quelque chose de malveillant?), Mais au-delà, vous devriez être bien.Un exemple de code a été demandé:
À mon service, j'ai ceci:
(
RefreshTask.REFRESH_DATA_INTENT
est juste une chaîne constante.)Dans mon activité d'écoute, je définis mon
BroadcastReceiver
:Je déclare mon récepteur en tête de la classe:
Je remplace
onResume
pour ajouter ceci:Et je remplace
onPause
pour ajouter:Maintenant, mon activité est à l'écoute de mon service pour dire "Hé, allez vous mettre à jour." Je pourrais transmettre des données au
Intent
lieu de mettre à jour les tables de base de données, puis revenir pour trouver les modifications dans mon activité, mais comme je veux que les modifications persistent de toute façon, il est logique de transmettre les données via DB.la source
Broadcasts
sont fantastiques et en plus si vous ne voulez pas que votre diffusion dépasse votre propre processus alors envisagez d'utiliser unLocalBroadcast
: developer.android.com/reference/android/support/v4/content/…Utilisez
LocalBroadcastManager
pour enregistrer un récepteur pour écouter une émission envoyée par un service local dans votre application, la référence se trouve ici:http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html
la source
LocalBroadcastManager
est désormais déconseillé au profit d'LiveData
autres outils de modèle d'observateur: developer.android.com/reference/androidx/localbroadcastmanager/…Je suis surpris que personne n'ait fait référence à la bibliothèque de bus de l'événement Otto
http://square.github.io/otto/
Je l'utilise dans mes applications Android et cela fonctionne parfaitement.
la source
android:process=":my_service"
ils ne sont pas en mesure de communiquer.L'utilisation d'un Messenger est un autre moyen simple de communiquer entre un Service et une Activité.
Dans l'activité, créez un gestionnaire avec un messager correspondant. Cela gérera les messages de votre service.
Le Messenger peut être transmis au service en l'attachant à un Message:
Un exemple complet peut être trouvé dans les démonstrations d'API: MessengerService et MessengerServiceActivity . Reportez-vous à l'exemple complet pour savoir comment fonctionne MyService.
la source
myService.send(message);
devrait être à lamessenger.send(message);
place.L'autre méthode non mentionnée dans les autres commentaires consiste à se lier au service à partir de l'activité à l'aide de bindService () et à obtenir une instance du service dans le rappel ServiceConnection. Comme décrit ici http://developer.android.com/guide/components/bound-services.html
la source
Vous pouvez également utiliser
LiveData
cela fonctionne comme unEventBus
.Ajoutez ensuite un observateur de votre
Activity
.Vous pouvez en savoir plus sur ce blog.
la source
Une autre façon pourrait être d'utiliser des observateurs avec une fausse classe de modèle à travers l'activité et le service lui-même, en implémentant une variation de modèle MVC. Je ne sais pas si c'est la meilleure façon d'y parvenir, mais c'est la manière qui a fonctionné pour moi. Si vous avez besoin d'un exemple, demandez-le et je posterai quelque chose.
la source
Ma méthode:
Classe pour gérer l'envoi et la réception de messages de / vers le service / l'activité:
Dans l'exemple d'activité:
Exemple en service:
Envoyer un message de l'activité / du service:
Comment cela fonctionne:
sur l'activité que vous démarrez ou liez le service. Les méthodes de service "OnBind" renvoient le classeur à son MessageManager, puis dans l'activité via l'implémentation des méthodes d'interface "Service Connection" "OnServiceConnected", vous obtenez cet IBinder et vous initiez à MessageManager. Une fois que l'activité a initié son MessageManager, le MessageHandler envoie et Handshake au service afin qu'il puisse définir son expéditeur "MessageHandler" (le "messager privé mMsgSender;" dans MessageManager). Ce faisant, le service sait à qui envoyer ses messages.
Vous pouvez également implémenter cela en utilisant une liste / file d'attente de "l'expéditeur" Messenger dans le MessageManager afin que vous puissiez envoyer plusieurs messages à différentes activités / services ou vous pouvez utiliser une liste / file d'attente de Messenger "récepteur" dans le MessageManager afin que vous puissiez recevoir plusieurs message de différentes activités / services.
Dans l'instance "MessageManager", vous avez une liste de tous les messages reçus.
Comme vous pouvez voir que la connexion entre "Activity's Messenger" et "Service Messenger" en utilisant cette instance "MessageManager" est automatique, cela se fait par la méthode "OnServiceConnected" et par l'utilisation de "Handshake".
J'espère que cela vous sera utile :) Merci beaucoup! Au revoir: D
la source
Pour suivre la réponse @MrSnowflake avec un exemple de code. Ceci est la XABBER maintenant open source de
Application
classe . LaApplication
classe centralise et coordonneListeners
et ManagerInterfaces et plus encore. Les gestionnaires de toutes sortes sont chargés dynamiquement.Activity´s
commencé dans le Xabber indiquera dans quel typeListener
ils sont. Et quandService
il démarre, il se présente à laApplication
classe comme commencé. Maintenant, pour envoyer un message àActivity
tout ce que vous avez à faire, c'est deActivity
devenir lelistener
type dont vous avez besoin. Dans leOnStart()
OnPause()
registre / non enregistré. IlsService
peuventApplication
simplement demander à la classelistener
de parler et si c'est le cas, l'activité est prête à recevoir.En parcourant la
Application
classe, vous verrez qu'il y a plus de butin que cela.la source
La liaison est une autre façon de communiquer
Implémenter l'interface dans l'activité
Fournir l'implémentation de la méthode
Lier l'activité au service
Enregistrez et annulez le rappel lorsque le service est lié et non lié à l'activité.
Initialiser le rappel
Appelez la méthode de rappel chaque fois que nécessaire
la source
serviceConnection
est sortionCreate
. Veuillez l'éditer.Comme mentionné par Madhur, vous pouvez utiliser un bus pour la communication.
En cas d'utilisation d'un bus, vous avez quelques options:
Bibliothèque de bus d'événements Otto (obsolète au profit de RxJava)
http://square.github.io/otto/
EventBus de Green Robot
http://greenrobot.org/eventbus/
NYBus (RxBus, implémenté en utilisant RxJava. Très similaire à l'EventBus)
https://github.com/MindorksOpenSource/NYBus
la source
Outre LocalBroadcastManager, Event Bus et Messenger ayant déjà répondu à cette question, nous pouvons utiliser Pending Intent pour communiquer à partir du service.
Comme mentionné ici dans mon article de blog
la source