93 votes

Attacher un service à une activité dans Android

Je suis en train d'essayer d'écrire un lecteur multimédia simple qui lit de l'audio en streaming en utilisant RTSP. J'ai une activité GUI et un service qui effectue la lecture. Ma question est de savoir comment communiquer au mieux entre l'activité et le service (par exemple, mettre à jour l'interface utilisateur en fonction de l'état du lecteur).

Je sais que je peux lier le service à l'activité en utilisant onBind(), mais si je comprends bien, cela arrêtera le service si l'activité est arrêtée. Je veux continuer la lecture même si l'utilisateur quitte l'activité. Y a-t-il une façon standard ou préférée de traiter ce problème?

156voto

Schildmeijer Points 10975

"Si vous démarrez un Service android avec startService(..), ce Service restera en cours d'exécution jusqu'à ce que vous invoquiez explicitement stopService(..). Il existe deux raisons pour lesquelles un service peut être exécuté par le système. Si quelqu'un appelle Context.startService(), le système récupérera le service (le créera et appellera sa méthode onCreate() si nécessaire) puis appellera sa méthode onStartCommand(Intent, int, int) avec les arguments fournis par le client. Le service continuera alors de fonctionner jusqu'à ce que Context.stopService() ou stopSelf() soit appelé. Notez que plusieurs appels à Context.startService() ne s'imbriquent pas (bien qu'ils entraînent plusieurs appels correspondants à onStartCommand()), donc peu importe le nombre de fois où il est démarré, un service s'arrêtera une fois que Context.stopService() ou stopSelf() sera appelé; cependant, les services peuvent utiliser leur méthode stopSelf(int) pour s'assurer que le service n'est pas arrêté tant que les intents de démarrage n'ont pas été traités.

Les clients peuvent également utiliser Context.bindService() pour obtenir une connexion persistante à un service. Cela crée également le service s'il n'est pas déjà en cours d'exécution (en appelant onCreate()onStartCommand(). Le client recevra l'objet IBinder que le service retourne de sa méthode onBind(Intent), permettant au client de faire des appels au service. Le service restera en cours d'exécution aussi longtemps que la connexion est établie (que le client conserve ou non une référence sur le IBinder du Service). En général, le IBinder retourné est pour une interface complexe qui a été écrite en AIDL.

Un service peut être à la fois démarré et avoir des connexions liées à lui. Dans un tel cas, le système maintiendra le service en cours d'exécution aussi longtemps qu'il est démarré ou qu'il existe une ou plusieurs connexions vers lui avec le drapeau Context.BIND_AUTO_CREATE. Une fois que aucune de ces situations ne prévaut, la méthode onDestroy() du Service est appelée et le service est effectivement terminé. Tous les nettoyages (arrêt des threads, désinscription des récepteurs) doivent être terminés avant de retourner de onDestroy()."

1 votes

Une petite confusion : Est-il vrai que si l'activité est détruite, le service sera également détruit ? Ou ce service n'est-il pas détruit seulement si j'implémente mon propre AIDL ? Je pose la question parce que lorsque j'utilise startService (en particulier avec IntentService), le service s'arrête lorsque son travail est terminé contrairement à lorsque l'activité meurt. Est-il vrai que si l'activité meurt, alors le service auquel elle est liée (exclusivement) meurt également ?

1 votes

Si vous utilisez un serveur simple en appelant startService, le service ne s'arrêtera pas tant que vous n'aurez pas appelé stopSelf() ou stopService(). Ensuite, si vous utilisez bindService, le service s'arrêtera si tous les composants connectés/libérés sont détruits.

1 votes

@UnKnown Si le service est démarré en utilisant startService(), alors peu importe si vous le liez ou le déliez, il continuera de fonctionner et ne pourra être détruit que en appelant stopService() ou stopSelf(). Donc, même si l'activité liée au service est détruite, le service ne sera pas détruit.

26voto

Hardik Gajera Points 54

Tout d'abord, 2 choses que nous devons comprendre

Client

  • il fait une demande à un serveur spécifique

    bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);`

ici, mServiceConn est une instance de la classe ServiceConnection (built-in), c'est en fait une interface que nous devons implémenter avec deux méthodes (1ère pour la connexion réseau et 2ème pour l'absence de connexion réseau) pour surveiller l'état de la connexion réseau.

Serveur

  • Il gère la demande du client et crée une réplique qui est privée au client qui a envoyé la demande et cette réplique du serveur s'exécute sur un thread différent.

Maintenant, du côté client, comment accéder à toutes les méthodes du serveur ?

  • le serveur envoie une réponse avec l'objet IBind. Donc l'objet IBind est notre gestionnaire qui accède à toutes les méthodes du service en utilisant l'opérateur (.).

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }

maintenant comment appeler la méthode qui se trouve dans le service

myservice.serviceMethod();

ici, myService est un objet et serviceMethode est une méthode dans le service. Et de cette façon, la communication est établie entre le client et le serveur.

10voto

Hefny Points 130

J'ai essayé d'appeler

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

par conséquent et j'ai pu créer un service sticky et m'y connecter. Tutoriel détaillé pour Exemple de service lié.

5voto

vrutberg Points 858

Il existe une méthode appelée unbindService qui prendra un ServiceConnection que vous aurez créé lors de l'appel à bindService. Cela vous permettra de vous déconnecter du service tout en le laissant tourner.

Cela peut poser un problème lorsque vous vous y connectez à nouveau, car vous ne savez probablement pas s'il fonctionne ou non lorsque vous redémarrez l'activité, vous devrez donc en tenir compte dans votre code d'activité.

Bonne chance!

-5voto

Mira Febriani Points 21

Si l'utilisateur annule, la méthode onDestroy() sera appelée. Cette méthode sert à arrêter tout service utilisé dans l'application. Donc, si vous souhaitez que le service continue même si l'utilisateur quitte l'application, il suffit d'effacer onDestroy(). J'espère que cela vous aidera.

0 votes

Tu devrais remplacer la fonction et supprimer l'appel par défaut à onDestroy() de la superclasse si ton IDE le crée automatiquement. Mais pourquoi voudrais-tu jamais faire cela?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X