Hintergrundausführungen in Flutter

Wie können periodische Aufgaben im Hintergrund ausgeführt werden?

Das Ausführen von Hintergrundaktivitäten kann für die optimale Nutzung von Apps sehr wichtig sein. Weil zu viele Hintergrundausführungen allerdings die Akkuleistung eines Devices schmälern, existieren in iOS und Android Begrenzungen, welche die Background Activities einer Applikation limitieren. In diesem Blogbeitrag zeigen wir, wie Hintergrundaufgaben in Flutter trotzdem ausgeführt werden können.

Background Activities in Apps sorgen für bestmögliches Nutzererlebnis

Das Ausführen von Hintergrundaktivitäten ist vor allem auf mobilen Endgeräten ein gängiger Anwendungsfall. Hierunter fallen beispielsweise

  • das Abrufen von Daten vom Webservice,
  • das Hochladen von Daten zum Webservice,
  • die GPS-Positionsermittlung zur Nachverfolgung einer Route und
  • Benachrichtigungen auf Basis von lokalem Verhalten innerhalb der App (Local Notifications).

Allerdings können Hintergrundaktivitäten die Akkuleistung enorm beeinträchtigen. Dabei kommt es generell auf die Komplexität und benötigte Rechenleistung der Aufgabe an, um diese auszuführen. Zudem muss das Betriebssystem diesen Prozess in der Pipeline behalten, damit er zu der angegebenen Zeit durchgeführt werden kann.

In den beiden gängigen mobilen Betriebssystemen Android und iOS existieren einige Barrieren, die das Ausführen von Hintergrundaktivitäten einschränken. Dadurch soll hauptsächlich die Akkuleistung optimiert bzw. das Batterieleben der Geräte verlängert werden. Um nun entsprechende Hintergrundaufgaben in Flutter ausführen zu können, werden im Folgenden zwei Bibliotheken vorgestellt und miteinander verglichen.

Der Flutter WorkManager

Der Begriff des WorkManagers kommt ursprünglich aus der Android-Welt. Dieses Flutter Plugin ist ein Wrapper um den WorkManager aus Android. Für iOS werden hier performFetchWithCompletionHandler und BGAppRefreshTask verwendet, um die Hintergrundausführung von Dart Code zu ermöglichen.

Android und iOS Setup

Damit die Hintergrundausführung des Dart Codes zugelassen werden kann, müssen einige Vorbedingungen für die jeweiligen Plattformen erfüllt werden. Diese sind sehr gut dokumentiert und straight-forward:

Nachdem diese Voraussetzungen erfüllt worden sind, kann das Plugin schließlich verwendet werden.

Beispiel 1: Wie realisiere ich Hintergrundausführungen in Flutter?

In diesem vereinfachten Beispiel wird aufgezeigt, wie eine Hintergrundaktivität mittels Dart Code in einer Flutter-Applikation umgesetzt werden kann. Die Darstellung soll eine Webservice-Kommunikation simulieren, welche zum Beispiel Daten wie Logs zum Webservice hochlädt.

Zunächst muss dafür der WorkManager initialisiert werden. Das passiert, nachdem die App gestartet wurde:

Hintergrundausführungen in Flutter | void main

Die Initialisierungsmethode erhält als Übergabeparameter einen Callback Dispatcher. Dieser wird ausgelöst, sobald der WorkManager eine registrierte Aufgabe, die im Hintergrund ausgeführt wird, detektiert. Der Dispatcher sieht im veranschaulichten Beispiel wie folgt aus:

Hintergrundausführungen in Flutter | callbackDispatcher

Anhand des task-Parameters kann festgestellt werden, um welche Aufgabe es sich handelt. So kann man dementsprechend darauf reagieren. In diesem Beispiel existiert lediglich eine Aufgabe, die vom WorkManager erkannt werden kann. Sobald der Task identifiziert wurde, wird folgende Methode aufgerufen:

Hintergrundausführungen in Flutter | backroundWebServiceCall

Dort wird ein Webservice Call simuliert, indem man hier mit einem kleinen Delay arbeitet.  Das kDebugMode sorgt dafür, dass der folgende Code nur in Debug Builds ausgeführt wird. Schlussendlich fehlen nur noch das Definieren und Registrieren der Aufgabe. Dies geschieht folgendermaßen:

Hintergrundausführungen in Flutter | executeHeavyPeriodicWork

Hierbei wird als erster Parameter ein eindeutiger Name vergeben, als zweiter Parameter der Name der Aufgabe festgelegt und als dritter Parameter die Häufigkeit mit übergeben. Anschließend wird jede 15 Minuten die simulierte Kommunikation zum Webservice aufgebaut und somit die Aufgabe ausgeführt.

Weitere Informationen zu Hintergrundausführungen in Flutter

Neben den erwähnten Customisations gibt es einige weitere Befehle, die teilweise nur unter Android verfügbar sind. Hierunter fallen:

  • Existing Work Policy: Gibt das gewünschte Verhalten an, wenn dieselbe Aufgabe mehr als einmal geplant wird
  • Initial Delay: Einen initialen Delay festlegen, bevor die Aufgabe erstmalig ausgeführt wird
  • Constraints (siehe Tabelle)
  • InputData: Eingabedaten für die Aufgabe. Gültige Datentypen sind hier:
    • Int
    • Bool
    • Double
    • String
    • Listen der oben genannten Datentypen
  • BackoffPolicy: Gibt die Wartestrategie an, sofern eine Aufgabe fehlgeschlagen ist. Gültige Werte sind hier:
    • Exponential: Wird verwendet, um anzugeben, dass der WorkManager die Backoff-Zeit exponentiell erhöhen soll
    • Linear: Wird verwendet, um anzugeben, dass der WorkManager die Backoff-Zeit linear erhöhen soll
  • Cancellation: Die Aufgabe abbrechen, anhand von:
    • Tag-Namen
    • Festgelegten eindeutigen Namen
    • Alle Aufgaben auf einmal

Die Alternative zum WorkManager: background_fetch

Eine weitere Möglichkeit, neben dem WorkManager-Plugin, bietet das background_fetch-Plugin, welches ebenfalls das Ausführen von Hintergrundaufgaben ermöglicht.

Android und iOS Setup

Ähnlich wie beim WorkManager-Modul existieren hier ebenfalls Setup-Guides für die dedizierten Plattformen:

Damit dieser Beitrag übersichtlich bleibt, wird lediglich – wie auch beim vorherigen Plugin – auf die Setup-Guides verwiesen.

Unser Fachbereich Flutter stellt sich vor

Die Entwicklungsplattform Flutter erfreut sich immer größerer Beliebtheit. Und auch unser Flutter-Team wächst stetig. Hier erfährst du mehr über unseren Fachbereich Flutter.

Beispiel 2: Simulation eines Webservice-Call

Dieser Anwendungsfall simuliert analog zum vorherigen Plugin einen Webservice-Call, welcher alle 15 Minuten ausgelöst werden soll. Um die Programmerweiterung nutzen zu können, muss diese zunächst initialisiert werden:

Hintergrundausführungen in Flutter | initPlatformState

Das background_fetch-Plugin kann wie folgt konfiguriert werden:

Hintergrundausführungen in Flutter | backroundConfiguration

Bei der Initialisierung wird die gezeigte Config übergeben. Dort können verschiedene Einstellungsmöglichkeiten vorgenommen werden:

Darüber hinaus existieren noch zwei wesentliche Callback-Funktionen. Der erste Callback-Block wird ausgelöst, sobald ein Event freigegeben wurde. Anhand der taskId kann identifiziert werden, um welche Aufgabe es sich hierbei handelt. Der zweite Callback-Block wird für Timeouts verwendet. Sobald eine Hintergrundaufgabe in ein Timeout läuft, kann dort eine entsprechende Behandlung durchgeführt werden:

Hintergrundausführungen in Flutter | _onEventTimeout

In diesem vereinfachten Beispiel wird lediglich der Timeout geloggt und die Hintergrundaufgabe beendet. Sofern die Hintergrundaktion korrekt ausgeführt beispielsweise das Event entsprechend ausgelöst wurde, kann der Callback für das erfolgreiche Auslösen verwendet werden:

Hintergrundausführungen in Flutter | _onEventReceived

Hier wird nun der simulierte Webservice-Call durchgeführt und schlussendlich auch die Aufgabe beendet. Die periodisch ausgeführte Hintergrundaufgabe in Flutter kann wie folgt registriert werden:

Hintergrundausführungen in Flutter | _registerBackround

Zusätzliche Anmerkungen zu Hintergrundausführungen in Flutter

Android

Unter Android wurde bereits der Headless-Mechanismus erwähnt. Dieser erlaubt es, Hintergrundaufgaben weiter auszuführen, auch wenn die App terminiert wurde. Diese Vorgehensweise ist allerdings nur unter Android möglich.

iOS

Unter iOS kann es sein, dass – abhängig von der Nutzung – Hintergrundaufgaben weniger oft ausgeführt werden. Wenn das Gerät länger nicht benutzt wurde, kann es vorkommen, dass Background Activities weniger oft ausgelöst werden. Außerdem werden keine weiteren Events und somit auch keine Hintergrundaufgaben mehr abgeschlossen, sobald die App terminiert wurde. Unter iOS existiert kein stopOnTerminate=false. Zudem werden keine neuen Events ausgelöst, sofern der Nutzer die App eine längere Zeit nicht mehr geöffnet hat.

Fazit

In diesem Blogbeitrag haben wir die Möglichkeiten zur Ausführung von Hintergrundaufgaben in Flutter aufgezeigt. Hierfür wurde sowohl das WorkManager-Plugin als auch das background_fetch-Plugin anhand von Beispielimplementierungen vorgestellt.

Beide Bibliotheken können für einmalige Operationen, die im Hintergrund ausgeführt werden sollen, sowie für periodische Aufgaben verwendet werden. Allerdings existieren bei beiden Plugins deutliche Einschränkungen unter iOS. Das liegt aber nicht an den Bibliotheken selbst, sondern hauptsächlich an den Restriktionen, die iOS bzw. Apple vorgibt. Beide Plugins arbeiten mit Callbacks, die verwendet werden können, sobald eine Aufgabe ausgeführt wird.

Das background_fetch-Plugin bietet zusätzlich noch die Option, gezielt auf Timeouts zu reagieren. Beide Plugins unterstützen Konfigurationen, um beispielsweise Hintergrundaufgaben nur auszuführen, wenn das Gerät ausreichend Akkuleistung besitzt. Abschließend kann gesagt werden, dass sich beide Bibliotheken nicht stark unterscheiden und es wohl eher eine Präferenzentscheidung ist. Android-Entwicklern könnte das WorkManager-Programmmodul zunächst vertrauter vorkommen, da es namentlich vom WorkManager aus Android abgeleitet ist. Die Implementierung an sich unterscheidet sich aber dennoch deutlich davon. Die Hintergrundausführung in Flutter ist aber dennoch recht einfach zu realisieren.

Mehr zu unseren Leistungen

×
Telefon

Sie sind auf der Suche nach einem Experten im Bereich App-Entwicklung? Wir freuen uns auf Ihre Nachricht!

+49 231 99953850
×