In meiner Anwendung habe ich eine Service
, die für die Pflege einer Bluetooth-Verbindung zu einem externen Gerät zuständig ist. Diese Service
-Klasse fragt das externe Bluetooth-Gerät periodisch nach Daten ab und fügt diese letzten Daten in ein Protokoll ein, das im Cache-Speicher (oder möglicherweise SD-Karte) gespeichert ist.
Unter den verschiedenen Activity
-Klassen, die ich habe, gibt es eine bestimmte Activity
, die die Hauptbenutzeroberfläche darstellt. Es ist dafür verantwortlich, die protokollierten Daten basierend auf den Cachedateidaten in grafischer Form anzuzeigen. Nennen wir das Activity
das Dashboard
. Der Benutzer kann in diesem Diagramm vor- und zurückblättern, um die seit dem Start der Anwendung im Cache gesammelten und protokollierten Daten zu überprüfen.
Für diese Frage müssen zwei Betriebsmodi betrachtet werden. Es ist möglich, dass der Benutzer die Option "Auf SD-Karte loggen" auswählt, wobei die Anwendung das Abrufen und Protokollieren auf SD-Karte fortsetzen muss, selbst wenn alle Activity
-Klassen getötet wurden (zB der Benutzer ist zurück zum Launcher gegangen) . In diesem Fall wird mein Service
mit .startService()
gestartet und läuft weiter und wird nur gestoppt, wenn der Benutzer die Anwendung erneut aufruft und die SD-Kartenprotokollierung deaktiviert. Der andere Modus ist, wenn der Benutzer nicht "auf SD-Karte loggen" ausgewählt hat, in welchem Fall die Service
immer noch die Bluetooth-Verbindung verwaltet, Abfragen und Logging in den Cache-Speicher zum Zweck der visuellen Anzeige der Daten auf der Grafik, Dies muss jedoch nur geschehen, solange Dashboard
Activity
verwendet wird.
Was ich zur Zeit habe, ist, dass die Dashboard
Activity
anfänglich an die Service
bindet, indem bindService()
verwendet wird, und einen entsprechenden Aufruf an unbindService()
innerhalb der onPause()
-Methode (sonst würde ich das tun) natürlich leck die Service
).
Das Problem besteht darin, dass Service
die Bluetooth-Verbindung aufrechterhalten und die Protokollierung bei Orientierungsänderungen fortsetzen muss oder wenn der Benutzer ein anderes Activity
über dem oberen Rand aufruft (z. B. eine E-Mail prüft). Wenn der Benutzer jetzt "auf SD-Karte loggen" ausgewählt hat, was zu einem Aufruf von startService()
führt, dann gibt es natürlich kein Problem. Das Problem ist natürlich, wie man zwischen einem Activity
, das zerstört wird, und dann wieder aufgrund von Änderungen der Ausrichtung (oder einer anderen Konfiguration) und der Zerstörung, weil der Benutzer zurück zum Launcher gegangen ist, unterscheiden kann. Im ersten Fall möchte ich nicht, dass das Service
-Datenloggen unterbrochen wurde. Im letzteren Fall möchte ich das Service
stoppen, wenn der Benutzer nicht "auf SD-Karte loggen" ausgewählt hat.
Die beste Lösung, die ich mir im Moment vorstellen kann, ist, dass der Dienst immer mit startService()
gestartet wird, so dass er weiter ausgeführt wird, wenn Dashboard
zerstört wurde. Was ich dann tun würde, ist ein Timeout innerhalb von Service
zu implementieren, wobei Service
sich selbst stoppt wenn kontinuierliche SD-Kartenprotokollierung nicht aktiviert ist, oder Dashboard
ist onCreate
d wieder innerhalb von fünf Sekunden (sagen wir) und bindet erneut an die Service
. Dies scheint ein wenig grob, und ich kann nicht umhin zu denken, dass dies ein gemeinsames Design-Problem sein muss, das eine bessere Lösung hat, die ich übersehen habe.
Ein Ansatz, den Sie verwenden könnten, ist zu überprüfen, ob die Aktivität isFinishing()
vor der Aufhebung in Ihrem onPause()
. Wenn es fertig ist, würden Sie die Entbindung auf Ihre onDestroy()
-Methode verschieben. Bevor onDestroy()
jedoch aufgerufen wird, können Sie Ihre ServiceConnection in der Methode onRetainNonConfigurationInstance()
beibehalten. Wenn Sie diese Persistenz durchführen, würden Sie unBind()
innerhalb von onDestroy()
überhaupt nicht aufrufen und die neue Instanz Ihrer Aktivität einfach losbinden.
Je nachdem, welche Anwendung Sie verwenden, können Sie Ihren Dienst einfach starten / stoppen.
Option 1: Wenn der Dienst zerstört werden soll, sofort nach Abschluss der Hauptaktivität.
Der Dienst wird nicht zerstört, wenn er vor dem Binden manuell gestartet wird:
%Vor%Stoppen Sie den Dienst nur, wenn Ihre Aktivität abgeschlossen ist!
%Vor%Option 2: Wenn das Betriebssystem entscheiden soll, wann der Dienst beendet wird.
%Vor%Wie Sie wahrscheinlich schon wissen, ist ein Service wirklich für einen separaten Lebenszyklus von Aktivitäten. Daher könnten Sie in Betracht ziehen, keinen Service für das reine Überwachungsszenario zu verwenden. Sie benötigen im Hintergrund nur einen Lebenszyklus getrennt von Aktivitäten, nicht jedoch im reinen Überwachungsfall.
Was Sie wirklich wollen, ist, dass Ihre Protokollierung an die Lebensdauer Ihrer Anwendung gebunden ist und dass Sie die Lebensdauer Ihrer Anwendung steuern können, indem Sie entweder Aktivitäten starten oder anhalten Bedienung. Wenn Sie Ihren Abruf in einem separaten Thread durchgeführt haben, auf den über das Anwendungsobjekt zugegriffen werden kann, müssen Ihre Aktivitäten überhaupt nicht mit einem Dienst verbunden sein, sondern lediglich mit diesem Protokollierungsthread kommunizieren. Wenn Sie die Hintergrundprotokollierung möchten, können Sie den Dienst starten / stoppen, der auch mit dem Protokollierungsthread kommunizieren würde, um beim Stoppen ordnungsgemäß zu bereinigen, neu zu starten, usw.
Sie sollten isChangingConfigurations()
, nicht isFinishing()
verwenden. : Letzteres ist false
sowohl im Fall einer Aktivität, die Sichtbarkeit verliert und wenn sich die Konfiguration ändert, so dass Sie nicht unterscheiden können.
Tags und Links android