2013-03-16 8 views
6

Ich baue eine App, die den Batteriezustand, die WLAN-Verbindung und die Standortdaten in regelmäßigen Abständen überwacht und die Ergebnisse in eine Datei schreibt (und sie später an einen Server sendet). Bei der Installation der App sollte die Überwachung deaktiviert werden - aber der Benutzer, der sie aktiviert, sollte einen Neustart überleben. Nach viel Lesen habe ich festgestellt, dass ich im Grunde 2 Optionen habe:Android-Design: Hintergrund lang laufenden Dienst oder AlarmManager?

  • Unterklasse Service und feuern Sie es von meiner Tätigkeit ab. Stellen Sie es auf den Vordergrund, STICKY und was nicht und hoffe, dass es nicht von Android getötet wird - und passen Sie auf, wenn android es neu erstellt (tatsächlich sollte es 3 Dienste geben, also könnte die Synchronisierung zwischen ihnen chaotisch sein). Starten Sie einen Thread im Dienst (keine Notwendigkeit für Executors ich denke) und haben Sie Thread.sleep(REGULAR_INTERVAL). Wach auf, sammle die Daten schreibe sie in eine Datei. Senden Sie die gesammelten Informationen und zeigen Sie sie auf meiner Aktivität an, wenn sie gerade ausgeführt wird (wodurch ein Broadcast-Empfänger registriert wurde). Spülen und wiederholen while(true). Haben Sie eine Möglichkeit, dies zu unterbrechen
  • Lassen Sie meine Aktivität eine PendingIntent mit AlarmManager registrieren - die jedes REGULAR_INTERVAL ausführen wird. Ich habe mir die technischen Details dieses Ansatzes nicht so genau angeschaut - aber ich hoffe, dass ich in der Lage sein werde, diesen PendingIntent zu erstellen und einen IntentService laufen zu lassen (das scheint der richtige Weg zu sein - die Thread-Maschinen kostenlos zu haben und herunterzufahren allein). Irgendein Skelett-Code für diesen Ansatz wäre willkommen.
  • Ich denke, ich muss einen Boot-Empfänger in beiden Fällen registrieren, um die Shared Preferences zu überprüfen (habe dies bereits getan) und im Fall 1 starten die Dienste, während 2 einen Empfänger für das Alarmereignis registrieren und setze den Alarm-Manager auf - das ist der Teil, den ich brauche ein Skelett-Code.

    Also - bevor ich anfange das zu bauen - was wäre der bevorzugte Ansatz?

    Im Rückblick - die App sollte einige Telefoneigenschaften überwachen und in eine Datei schreiben, bis der Benutzer sich entscheidet, sie auszuschalten.

    +0

    Ihre Benutzer werden Sie wahrscheinlich töten, wenn Sie eine 'Service' am Leben zu halten ständig ihre Handy-Akku zu belasten nur Kuppel Daten in bestimmten Zeitintervallen zu sammeln. Verwenden Sie den zweiten Ansatz mit einem 'IntentService' mit zusätzlichen WakeLocks, falls nötig (schauen Sie sich den 'WakefullIntentService' von CommonsWare an). – Luksprog

    +0

    @Luksprog: danke - würde ich Schlösser brauchen? in dem Rundfunkempfänger, der den Alarm empfangen würde (immer noch im Hinblick darauf, wie genau dies implementiert werden sollte)? –

    +0

    Warum die negative Stimme? –

    Antwort

    6

    während im Fall 2 einen Empfänger für den Ereignisalarm registrieren und die Alarmmanager

    Ihren Empfänger eingerichtet wird bereits über das Manifest registriert werden.

    Welches wäre der bevorzugte Ansatz?

    AlarmManager, REGULAR_INTERVAL vorausgesetzt ist typischerweise decently lang (beispielsweise über ein paar Minuten). Im Idealfall ist dieses Intervall vom Benutzer konfigurierbar.

    Wenn Sie dies auch dann tun möchten, wenn das Gerät anderweitig schläft, funktioniert Ihre Option # 1 einfach nicht, es sei denn, Sie halten die ganze Zeit WakeLock, was Ihre Benutzer dazu bringen könnte, Sie ins Gesicht zu schießen mit einer Schrotflinte.

    Einige Skelett-Code für diesen Ansatz wäre willkommen.

    Here is a sample app demonstriert die Verwendung von AlarmManager für nicht _WAKEUP Alarme (das heißt, Sie müssen nur diese Ereignisse auftreten, während das Gerät aus anderen Gründen schon wach ist).

    Here is a sample app zeigt die Verwendung von AlarmManager für _WAKEUP Alarme, mit my WakefulIntentService. WakefulIntentService (oder etwas Ähnliches) ist notwendig, weil AlarmManager das Gerät nicht sehr lange wach hält (gerade lang genug für onReceive() von BroadcastReceiver), und Sie müssen zusätzliche Schritte unternehmen, um das Gerät lange genug wach zu halten, damit Sie es tun können Arbeit. Theoretisch, Ihre Arbeit könnte schnell genug sein, nur in onReceive() von BroadcastReceiver zu tun, die Notwendigkeit zu vermeiden, mit der WakefulIntentService zu verwirren. Sie werden jedoch jedes Mal Festplatten-E/A durchführen, was idealerweise nicht im Hauptanwendungs-Thread erfolgen sollte, in dem onReceive() aufgerufen wird. Und wenn Sie Ihre Daten hochladen, brauchen Sie vielleicht auch eine WakefulIntentService, wenn Sie auch im Hintergrund arbeiten wollen.

    +0

    Danke - warum registriere ich den BroadcastReceiver im Manifest (nicht der Boot eins - das muss da sein)? Würde das nicht bedeuten, dass es die ganze Zeit registriert wird - was zu einem Mehraufwand führt? Während BootReceiver -> 'Überwachung aktiviert ist? (einen Empfänger für den Alarm registrieren; den Alarm einrichten): Rückkehr erscheint sparsamer. Auch der AlarmReceiver läuft in meinem Haupt-UI-Thread? Dies ist der Fall, wenn meine Aktivität (die nur die erfassten Daten anzeigt und das Aktivieren/Deaktivieren der Überwachung ermöglicht) aktiv ist - nein? Sonst gäbe es keinen UI-Thread (oder es würde keinen Unterschied machen) - irre ich mich? –

    +0

    @Mr_and_Mrs_D: "Warum registrieren Sie den BroadcastReceiver im Manifest" - andernfalls müssen Sie ständig eine Komponente (z. B. Dienst) bereithalten, die den Ausgangspunkt für den Wechsel zu "AlarmManager" darstellt. Sie wollen die ganze Zeit nicht mit Speicher arbeiten. "Würde das nicht bedeuten, dass es die ganze Zeit registriert wird - was zu einem Overhead führt?" - Es wird nur von Ihrem 'AlarmManager' verwendet. "Auch der AlarmReceiver wird in meinem Haupt-UI-Thread ausgeführt?" - 'onReceive()' von 'BroadcastReceiver' wird im Hauptanwendungs-Thread aufgerufen. – CommonsWare

    +0

    @Mr_and_Mrs_D: "Sonst gäbe es keinen UI-Thread" - es gibt immer einen "UI-Thread", genauer gesagt "Hauptanwendungs-Thread". Wenn Sie zu viel Zeit mit dem Hauptanwendungs-Thread verbringen, selbst wenn Sie 'onReceive()' haben, beendet Android Ihren Vorgang. – CommonsWare

    0

    Abhängig von der Länge der wiederkehrenden Aufgabe können Sie einen von mehreren Ansätzen wählen. Diese Frage behandelt sie - Scheduling recurring task in Android

    Verwenden eines AlarmManager ist praktisch, wenn Task Schlafzeiten 15 Minuten oder länger sind. Das Muster ist bekannt.

    +0

    @CommonsWare: Ich habe ähnliche Situation, um eine Aufgabe (GPS-Positionierung) im Intervall von 1 min durchzuführen. Ich verwende Handler dafür in meiner Hauptaktivität, wie wird es meine Anwendung beeinflussen – Tushar

    Verwandte Themen