Ich habe einen Dienst, der ständig nach neuen Aufgaben sucht. Wenn es eine neue Aufgabe gibt, möchte ich die Benutzeroberfläche der Aktivität aktualisieren, um diese Informationen anzuzeigen. Ich habe https://github.com/commonsguy/cw-andtutorials/tree/master/18-LocalService/ in diesem Beispiel gefunden. Ist das ein guter Ansatz? Irgendwelche anderen Beispiele?
Vielen Dank.
Antworten:
Unten finden Sie meine ursprüngliche Antwort - dieses Muster hat gut funktioniert, aber seit kurzem verwende ich einen anderen Ansatz für die Service- / Aktivitätskommunikation:
Verwenden Sie RxJava, um asynchrone Operationen auszuführen.
Wenn der Dienst Hintergrundvorgänge fortsetzen muss, auch wenn keine Aktivität ausgeführt wird, starten Sie den Dienst auch über die Anwendungsklasse, damit er nicht gestoppt wird, wenn er nicht gebunden ist.
Die Vorteile, die ich bei diesem Ansatz gegenüber der startService () / LocalBroadcast-Technik gefunden habe, sind:
Ein Beispielcode. Zuerst der Service:
Und eine Aktivität, die an den Dienst gebunden ist und Aktualisierungen der Druckhöhe erhält:
Das Layout für diese Aktivität lautet:
Wenn der Dienst im Hintergrund ohne gebundene Aktivität ausgeführt werden muss, kann er auch über die Anwendungsklasse gestartet
OnCreate()
werdenContext#startService()
.Meine ursprüngliche Antwort (von 2013):
In Ihrem Dienst: (Verwenden von COPA als Dienst im folgenden Beispiel).
Verwenden Sie einen LocalBroadCastManager. Richten Sie in onCreate Ihres Dienstes den Sender ein:
Wenn Sie die Benutzeroberfläche über etwas informieren möchten:
In Ihrer Aktivität:
Erstellen Sie einen Listener auf onCreate:
und registrieren Sie es in onStart:
quelle
onStart()
oder IhreonResume()
Methode geeignet ist . Im Allgemeinen ist es vernünftig anzunehmen, dass das Ergebnis nicht mehr benötigt wird, wenn die Aktivität den Dienst auffordert, etwas zu tun, aber vor Erhalt des Ergebnisses beendet wird. Ebenso sollte beim Starten einer Aktivität davon ausgegangen werden, dass keine ausstehenden Anforderungen vom Service verarbeitet werden.Für mich war die einfachste Lösung, eine Sendung zu senden. In der Aktivität oncreate habe ich die Sendung wie folgt registriert und definiert (updateUIReciver ist als Klasseninstanz definiert):
Und von dem Dienst senden Sie die Absicht wie folgt:
Vergessen Sie nicht, die Wiederherstellung in der Aktivität "Zerstören" aufzuheben:
quelle
Ich würde einen gebundenen Dienst verwenden, um dies zu tun und mit ihm zu kommunizieren, indem ich einen Listener in meiner Aktivität implementiere. Wenn Ihre App myServiceListener implementiert, können Sie sie als Listener in Ihrem Dienst registrieren, nachdem Sie sie gebunden haben. Rufen Sie listener.onUpdateUI von Ihrem gebundenen Dienst aus auf und aktualisieren Sie dort Ihre Benutzeroberfläche!
quelle
Ich würde empfehlen, Otto zu testen, einen EventBus, der speziell auf Android zugeschnitten ist. Ihre Aktivität / Benutzeroberfläche kann Ereignisse abhören, die vom Dienst auf dem Bus veröffentlicht wurden, und sich vom Backend entkoppeln.
quelle
Die Lösung von Clyde funktioniert, aber es handelt sich um eine Sendung, von der ich mir ziemlich sicher bin, dass sie weniger effizient ist als das direkte Aufrufen einer Methode. Ich könnte mich irren, aber ich denke, die Sendungen sind eher für die Kommunikation zwischen Anwendungen gedacht.
Ich gehe davon aus, dass Sie bereits wissen, wie Sie einen Dienst an eine Aktivität binden. Ich mache so etwas wie den folgenden Code, um diese Art von Problem zu lösen:
Ich habe Bits für die Thread-Sicherheit weggelassen, was wichtig ist. Stellen Sie sicher, dass Sie Sperren oder ähnliches verwenden, wenn Sie die Fragmentreferenzen für den Dienst überprüfen und verwenden oder ändern.
quelle
quelle
Meine Lösung ist möglicherweise nicht die sauberste, sollte aber ohne Probleme funktionieren. Die Logik besteht einfach darin, eine statische Variable zu erstellen, um Ihre Daten auf dem zu speichern
Service
und Ihre Ansicht jede Sekunde auf Ihrem zu aktualisierenActivity
.Nehmen wir an, Sie haben eine
String
auf IhremService
, die Sie an eineTextView
auf Ihrem senden möchtenActivity
. Es sollte so aussehenDein Dienst:
Ihre Aktivität:
quelle
android
Versuchen Sie im Kontext von yes, wenn es sich um eine Liste handelt, einen Adapter zu erstellen oder Daten mit sqllite / Realm DB beizubehalten.