Frage Binden Sie den Dienst an Aktivitäten in Android


Ich versuche, einen einfachen Media Player zu schreiben, der Streaming-Audio mit RTSP abspielt. Ich habe eine GUI-Aktivität und einen Dienst, der die Wiedergabe durchführt. Meine Frage ist, wie man am besten zwischen der Aktivität und dem Dienst kommuniziert (z. B. Aktualisieren der GUI basierend auf dem Spielerstatus).

Ich weiß, dass ich den Dienst mithilfe onBind () an die Aktivität binden kann, aber wenn ich das richtig verstehe, wird der Dienst beendet, wenn die Aktivität beendet wird. Ich möchte die Wiedergabe fortsetzen, auch wenn der Benutzer die Aktivität beendet. Gibt es einen standardisierten oder bevorzugten Weg, um mit diesem Problem umzugehen?


75
2017-12-16 17:28


Ursprung


Antworten:


"Wenn Sie einen Android-Dienst mit starten startService(..) Dieser Dienst wird so lange ausgeführt, bis Sie ihn explizit aufrufen stopService(..). Es gibt zwei Gründe, warum ein Dienst vom System ausgeführt werden kann. Wenn jemand anruft Context.startService() Dann ruft das System den Dienst ab (erstellt ihn und ruft ihn auf) onCreate() Methode, wenn nötig) und rufen Sie dann seine onStartCommand(Intent, int, int) Methode mit den vom Client gelieferten Argumenten. Der Dienst wird zu diesem Zeitpunkt weiter ausgeführt Context.stopService() oder stopSelf() wird genannt. Beachten Sie, dass mehrere Anrufe an Context.startService() nicht verschachteln (obwohl sie zu mehreren entsprechenden Aufrufen führen onStartCommand()), egal wie oft es gestartet wird, wird ein Service einmal gestoppt Context.stopService() oder stopSelf() wird genannt; jedoch können Dienste ihre verwenden stopSelf(int) Methode, um sicherzustellen, dass der Dienst nicht gestoppt wird, bis die gestarteten Absichten verarbeitet wurden.

Kunden können auch verwenden Context.bindService() um eine beständige Verbindung zu einem Dienst zu erhalten. Dadurch wird der Dienst ebenfalls erstellt, wenn er nicht bereits ausgeführt wird (Aufruf onCreate() während dabei), aber nicht anruft onStartCommand(). Der Kunde erhält die IBinder Objekt, das der Dienst von seinem zurückgibt onBind(Intent) Methode, die es dem Client ermöglicht, dann zu dem Dienst zurückzurufen. Der Dienst wird so lange ausgeführt, wie die Verbindung hergestellt wurde (unabhängig davon, ob der Client eine Referenz auf dem Dienst beibehält oder nicht IBinder). Normalerweise die IBinder zurückgegeben wird für eine komplexe Schnittstelle, die in AIDL geschrieben wurde.

Ein Dienst kann sowohl gestartet werden als auch über Verbindungen verfügen. In diesem Fall hält das System den Dienst so lange in Betrieb, wie er gestartet wurde oder mit dem eine oder mehrere Verbindungen bestehen Context.BIND_AUTO_CREATE Flagge. Sobald keine dieser Situationen mehr besteht, ist der Service onDestroy() Methode wird aufgerufen und der Dienst wird effektiv beendet. Alle Aufräumarbeiten (Anhalten von Threads, Aufheben der Registrierung von Empfängern) sollten nach der Rückkehr abgeschlossen sein onDestroy(). "


139
2017-12-16 18:27



Zuallererst, 2 Dinge, die wir verstehen müssen

Klient

  • es wird eine Anfrage an einen bestimmten Server gestellt

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

Hier mServiceConn ist eine Instanz von ServiceConnection Klasse (eingebaut) es ist eigentlich Schnittstelle, die wir mit zwei (1. für Netzwerk verbunden und 2. Netzwerk nicht verbunden) Methode zur Überwachung des Netzwerkverbindungsstatus implementieren müssen.

Server

  • Er verarbeitet die Anforderung des Clients und erstellt eine eigene Replik, die nur für den Client privat ist, der die Anforderung sendet, und diese Replik des Servers wird auf einem anderen Thread ausgeführt.

Jetzt auf Clientseite, wie auf alle Servermethoden zuzugreifen?

  • Antwort des Servers senden mit IBind Object.so IBind-Objekt ist unser Handler, der mit dem Operator (.) auf alle Methoden des Dienstes zugreift.

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

Jetzt, wie man Methode nennt, die im Dienst liegt

myservice.serviceMethod();

Hier myService ist Objekt und serviceMethode ist eine Methode in Betrieb. Und auf diese Weise wird die Kommunikation zwischen Client und Server hergestellt.


20
2017-08-22 07:24



ich habe versucht anzurufen

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

folglich und ich könnte einen klebrigen Service schaffen und an ihn binden. Ausführliches Tutorial für Gebundenes Servicebeispiel.


8
2018-05-09 16:08



Es gibt eine Methode namens unbindService Dies erfordert eine ServiceConnection, die Sie beim Aufruf von bindService erstellt haben. Auf diese Weise können Sie die Verbindung mit dem Dienst trennen, während Sie ihn weiterhin ausführen.

Dies kann ein Problem darstellen, wenn Sie erneut eine Verbindung herstellen, da Sie wahrscheinlich nicht wissen, ob es ausgeführt wird oder nicht, wenn Sie die Aktivität erneut starten. Sie müssen dies in Ihrem Aktivitätscode berücksichtigen.

Viel Glück!


5
2017-12-16 17:38



Dies ist eine voreingenommene Antwort, aber ich habe eine Bibliothek geschrieben, die die Verwendung von Android Services vereinfachen kann, wenn sie lokal im selben Prozess wie die App ausgeführt werden: https://github.com/germnix/acacia

Im Grunde definieren Sie eine mit @Service und seiner implementierenden Klasse annotierte Schnittstelle, und die Bibliothek erstellt und bindet den Dienst, verarbeitet die Verbindung und den Hintergrund-Worker-Thread:

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

Sie können eine Instanz des zugehörigen android.app.Service abrufen, um persistente Benachrichtigungen zu verbergen / anzuzeigen, Ihren eigenen android.app.Service zu verwenden und das Threading manuell zu bearbeiten.


-1
2018-05-02 16:42



Wenn der Benutzer zurückgeht, wird der onDestroy() Methode wird aufgerufen. Mit dieser Methode wird jeder Dienst gestoppt, der in der Anwendung verwendet wird. Wenn Sie also den Dienst fortsetzen möchten, selbst wenn der Benutzer die Anwendung beendet, löschen Sie einfach onDestroy(). Ich hoffe das hilft.


-4
2018-04-29 13:16