Flutter: Flutter should provide an abstraction for background execution

Created on 2 May 2016  ·  139Comments  ·  Source: flutter/flutter

Customers would like to execute dart code as background processes on both iOS and Android, for things like syncing down data when wifi is available but the app is not open, etc.

@mpcomplete created a background process on Android to execute Dart code to update flutter. But I'm not aware of a parallel on iOS.

This issue tracks the development of APIs in plugins or otherwise. Engine support for these abstractions is tracked in https://github.com/flutter/flutter/issues/6192.

truckable wellbeing engine framework plugin new feature

Most helpful comment

Quick update: background execution for iOS is implemented and up for review (PR flutter/engine#5539). Once that lands, I'll start on updating the Android background execution to have a consistent interface and publish a sample plugin. This will all hopefully be done by end of month.

All 139 comments

Should the code that runs in the background be written in Dart or in Java/Objective-C ?

This came up in the context of wanting to update the local data model when connectivity was available. e.g. subway maps/times when you might be walking in/out of a subway. So I think the goal would be to have the executed code be Dart so you didn't have to have separate data-model-manipulation code for each platform.

CC @kasperl; we have explored many ways of executing code in the background across our various targets, and perhaps some learnings could be drawn from that.

Do we have some use cases from our users? The only one that I heard was "We want to run some code on the device, in response to a push message. We want to sync the data onto the device, even if the app isn't open."

It's typically pretty restricted what an app is actually allowed to do in the background, so in this case I think we can get inspiration for the use cases from there. For example, here is the iOS model:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

I believe this is the same bug as #6192, yes.

Adding leafy tag and milestone value from #6192

@mravn-google @sigurdm something to think about!

Assigning to Mikkel for a very initial investigation to better understand feasibility and cost.

Here's an update from Leafy:

Due to limitations of data notifications (i.e. notifications that require app to respond in some way), leafy is leaning towards using display notifications (i.e. notifications that are pushed directly to user screen without app involvement). Support for these already exist in Flutter.

However, during conversations with other teams another use case has surfaced: If you want to support wearables or [home screen] widgets from your app, you would need to write the UI in native code since these surfaces are not yet supported by Flutter. However, it would be nice to be able to "wake up the app and ask for data" so that the model layer and business logic can be shared across the flutter app and the wearable app. Having never written one of these, I am not sure how existing native apps do this but it certainly seems like a valid use case for background tasks.

Just talked to author of Flutter talk for Berlin DroidCon, and this was one of his top asks. "How to do this, the Flutter way"

To be clear, it is currently possible to write background processes as part of a Flutter-using App. However those processes can only execute Obj-C/Swift or Java/Kotlin code. This bug is about fixing the limitation in our engine to allow executing Dart code in these background processes, as well as possibly providing an abstraction to allow scheduling such background work from Dart (likely that belongs in a plugin once the FlutterView-needs-to-be-on-screen restriction is removed).

https://github.com/flutter/flutter/issues/6192#issuecomment-258928555 discusses the current engine limitation and our intention to solve it. FYI @a-siva

This is also related to (a duplicate of?) https://github.com/flutter/flutter/issues/5048.

We have a use case I do not see mentioned: We are location tracking every 5 seconds, and have certain other information being attached to that event, all of which business logic is implemented in Dart. If our user brings another activity to the foreground, we need to display a persistent notification and continue to run that Dart code every 5 seconds.

This is a blocker for us. I'd be interested in hearing any workarounds we could implement at the moment, since this will delay shipment.

I would try to simply leave the timer active and see what happens. I wouldn't think it would be reliable but our app also has a use case of one-time cache cleanup (15 minutes after app has been put to background) and we have seen it successfully execute. We schedule it while the app is being stopped in Dart. Something like this:

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused) {
        new Future.delayed(const Duration(seconds: 5), () => _doSomething());
    }
}

It would not work if:

  • App is explicitly killed by user (e.g. from the task switcher).
  • App is killed by OS due to memory pressure.
  • On iOS? I don't think we have tried that so please feel free to try and report back.

I'm not sure of the iOS counterparts, but on Android a flutter plugin could be created that launches a foreground service, which gives the process a higher priority and makes it less likely to be killed during resource demanding times. Would this also give the long running Dart timer a better chance of survival?

Yes, that might help since your activity (thus your flutter view) will remain active. I am still not convinced that we have enough clarity to do a plugin.

If the point is to support periodic background polling of information, it might be better to design a plugin just for that. It should allow registering a callback in Dart that is invoked via a timer in native code rather than implementing the Timer in Dart. We could do that with a service on Android.

OR

We could simply have a HowTo for creating KeepAlive™ Flutter apps.

On iOS, you can set an UIBackgroundMode in your Info.plist to make it much less likely for the app to be killed.

On Android, setup an empty service. This is mostly AndroidManifest.xml change + a trivial service class implementation.

A generic KeepAlive plugin does not seem to be workable as it would still require manual setup on iOS and isn't clear whether to use foreground/background service on Android (foreground service is tougher to kill but requires a persistent notification).

Even with a foreground service, the OS could still kill our process for any reason.

I feel the ideal solution must utilize Android's Alarm Manager, which is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. But even with this, how might we reboot the Dart process with the same state, since we'll have a logged-in Firebase user making authenticated database writes?

@pauldemarco hence this bug... There's no way for Flutter right now to execute Dart code in any state w/o a FlutterView running. This includes Alarm Manager, Wearable/Native Widget Data Sync, or Push Notifications (though the use case for the last one is slowly going away https://github.com/flutter/flutter/issues/6192).

I would think the _same state_ issue should be resolved at app level not at Flutter level. For native apps you have the same problem. Once a process is dead, you cannot recover state unless you save it somewhere (shared preferences or sqlite for instance). Presumably you would do the same in your Dart code. One thing Flutter can do is to communicate messages such as applicationWillTerminate on iOS and onSaveInstanceState on Android so you can prepare yourself for this.

Questions:

  • What are the iOS and Android models for background execution?

    • What signals can trigger the application to run?

    • How long do you have to run? How do you know when that's running out?

  • What execution model do we want for background execution? (e.g. a separate isolate? Use the main dart:ui thread?)
  • Do we want to support code running without the app (as in runApp) having first run?
  • Can we collect a canonical list of use cases?

Currently this isn't planned for the near future. It's a large process, we would need to move something else off our short-term priority list to do this soon.

Use case
We have different modes of operation that record events at different intervals (5 seconds, 10 minutes, 30 minutes, 6 hours). We need a way to ensure the logging process runs whether or not the app is currently running.

What signals can trigger the application to run?

On Android this would be via a PendingIntent that is sent from a scheduled Alarm in AlarmManager.
I'm not sure of the iOS counterpart to this at the moment.

How long do you have to run? How do you know when that's running out?

We must first gather needed information for the event, some of which is async (GPS Location), then record the event in an online datastore (Firebase). This entire process can last up to 30 seconds.

What execution model do we want for background execution? (e.g. a separate isolate? Use the main dart:ui thread?)

I don't think this matters to us, we won't be doing any expensive computation.

Do we want to support code running without the app (as in runApp) having first run?

I'm not sure of the implications here. I suppose since we initialize our business logic and state in the normal app, it would be best to have that stuff run first, so we can utilize crash reporting etc.

I can add another user case, this functionality is the only thing keeping me from finalizing my app. I had an android app for this and decided to create a newer, better version that ideally also works on iOS. I am not familiar with the components in iOS (when researching I found that background tasks in iOS are a lot more restricted than on android) but I can name the Android components I used.

What signals can trigger the application to run?

Most of the code is triggered by an Alarm in AlarmManager as well.

However, to start that alarm all the time some code is executed on device boot and also on package upgrade (android.intent.action.MY_PACKAGE_REPLACED) because previous alarms would be removed.

How long do you have to run? How do you know when that's running out?

Ideally for under a second. A small network request is made and the result is persisted, in some cases a notification is displayed. After that the method returns.

What execution model do we want for background execution? (e.g. a separate isolate? Use the main dart:ui thread?)

Does not matter to me as well.

Do we want to support code running without the app (as in runApp) having first run?

In my case after running once would be fine, however if something like a boot receiver is possible, it should run even if the app wasn't started before.

https://stackoverflow.com/questions/41924890/how-do-i-run-code-in-the-background-even-with-the-screen-off is Flutter's most-viewed stack overflow question as far as I can tell. :) There definitely seems to be interest in this space.

https://github.com/flutter/flutter/issues/6192 was reactivated to provide the underlying support for actually running Dart code when a FlutterView is not rendering.

This is on our near-term radar, but will be a few months at least.

Sorry un-assigning @zanderso from this bug, I meant to assign him to the underlying background execution bug (#6192)

CC @kasperl; we have explored many ways of executing code in the background across our various targets, and perhaps some learnings could be drawn from that.

@mit-mit did you document your findings in some shape or form?

Another reason to want background processing is if you want to create a Streaming Audio app. The user open the app to start an audio stream. The background process downloads the stream and plays the audio end receives events to start/stop/pause/ff/rewind end sends events to change UI e.g the the seekbar audio meta data to ui. You need a background process for when the user leaves your apps ui the download/playing of the stream needs to continue

We are currently working on this. No ETA at this time.

@zanderso posted an updated over here: https://github.com/flutter/flutter/issues/6192#issuecomment-342214725

@a-siva informs me that this is still ongoing; Android is up and running and we're working on iOS now.

We have a use case for this where we would like to track user location in the background to register whether or not they went to a specific location at a specific time (ie. during an event).

@bjornbjorn can't you use geo fences for that? don't know if IOS has something similar but you can achieve this Play Service Geofencing

are there any news @Hixie ? I am currently in the stage where I need my app to run as a background service (most of the app is written in Go) but it gets eventually killed. I started implementing foreground service in Java side but it's going to be pretty nasty if I have to reimplement it eventually for iOS.

Some estimate whether this will be available for android in the next week or next month would be really appreciated :)

@rusenask as detailed over in https://github.com/flutter/flutter/issues/6192, we now have a plugin for this on Android! Please take a look at https://pub.dartlang.org/packages/android_alarm_manager, and let us know if that satisfies your requirements.

It looks promising and I could probably change my app from "daemon" style to more like "periodic bursts" with that alarm manager. To wake up, consume any news and shutdown.

However, ideally I would use something that allows my process to always run in the foreground. https://stackoverflow.com/questions/15758980/android-service-needs-to-run-always-never-pause-or-stop . In short, my app runs a bot so it pretty much always needs to run.

We will need to make sure we have documented this before we consider this done.

Should we open a new documentation issue?

@zanderso -- @mjohnsullivan is the best contact for the documentation side.

Is the ETA known?

@it2bz ETA for what exactly? Support on Android? Documentation? Support on iOS? Examples?

@Hixie Support on Android and iOS and at least basic documentation with examples

For iOS, can you elaborate on exactly what you would like? Apple has strict restrictions on what applications can do in the background, so it would be useful for us to know exactly which APIs you want us to hook into.

I'm looking for opportunity background work with user location

Looks like this is the 'ask background stuff' thread so I'll start. I wanted to implement a music player using flutter but am unsure if it would be possible (API wise) to keep the music playing even if the app is minized on the phone. I know that on Android you could start a service which would actually be able to continue even if the app gets closed. It would then relaunch the activity if needed. Is something similar possible on flutter right now?

@SirWindfield Your best bet would be to use each platform's native media player API, which will keep playing separately from the app.

@kirbyfan64 I thought so, thank you!

@Hixie , a solution like this (Cordova): https://github.com/katzer/cordova-plugin-background-mode, or like this (Swift): https://github.com/yarodevuci/backgroundTask would be nice for Flutter background tasks.

@holospeed Those are approaches that Apple would likely not let you ship, so I'm guessing we wouldn't want to spend time implementing this ourselves. It's certainly something we welcome you to implement as a community-contributed package on pub, if you care about personal apps on iOS, though.

Maybe a solution would be to make specific background plugins like a plugin for audio playback in the background, and a plugin for GPS/Location in the background etc. instead of trying to create a abstract background mechanism which needs to support everything.

Is it possible to run a timer in the background that brings the app to the
foreground at a certain time?

On Wed, 21 Mar 2018 at 08:49, Dylan Drost notifications@github.com wrote:

Maybe a solution would be to make specific background plugins like a
plugin for audio playback in the background, and a plugin for GPS/Location
in the background etc. instead of trying to create a abstract background
mechanism which needs to support everything.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/flutter/flutter/issues/3671#issuecomment-374867947,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AK-c-E0KdEkvbH5uCBIM8FaAbYQkSU2tks5tghQWgaJpZM4IVsUk
.

@iBob101 I believe this is possible if you use the android_alarm_manager plugin in combination with the android_intent plugin.

In my use case All background tasks i need are to play audio in the background at certain time so i think @aegis123 suggestion is great we can start small and by time provide mechanism that support any background process

I also need this for playing music in the background.

I've been looking at how this has been done in the android_alarm_manager plugin and from what I can gather, a Dart code is invoked on the Android by calling runFromBundle. The Dart function invoked is specified by the entrypoint, however what if that function needs information to be passed? Sample use case would a chat app that allows for direct replies via notifications. As per this link, the notification will allow remote input but it does not seem like it would be possible pass the text that has been read over to the Dart function so it can be processed so that the reply can be sent.

Another example is an email application that shows a notification when a new email has been received, actions may be presented one of which could be the ability to archive the email, which is done by a Dart function. However, that function would need to know which email needs to be archived.

@MaikuB you could make a PR to allow a dictionary to be passed around that can hold key value pairs.

Generally speaking though, for my usage example, I would need something similar to androids Service component. And since flutter is not designed to have every single API available that each OS can provide, it might actually be a better idea to write the app in kotlin/java oder swift.

I believe @bkonyi is currently looking at what we can do on iOS for this issue.

This means we cannot have background service with Flutter? For example: A service to popup push notifications from the server.

@s-bauer Always running is not a thing for Android, unless maybe foreground notifications, but I didn't find mentions of startForeground on your code.

I'm not sure what are your specs but remember that android phones go to deep sleep after a few hours with the screen off and not being moved. All services (except foreground) are going to be scheduled however the operating system thinks it's best. A push notification coming from FCM or an alarm coming from AlarmManager under a specific set up are maybe the only 2 things under a developer's control that are capable of waking up an android device / app whenever the developer wishes, but not for an indefinite amount of time. There are lots of other methods that depend on whatever the operating system thinks it's best for the battery. See about doze mode for more details. https://developer.android.com/training/monitoring-device-state/doze-standby

On iPhone things are much more restricted.

Also I don't see why a service or connection must stay alive in order to receive push notifications from FCM or APNS, maybe I'm missing something?

Quick update: background execution for iOS is implemented and up for review (PR flutter/engine#5539). Once that lands, I'll start on updating the Android background execution to have a consistent interface and publish a sample plugin. This will all hopefully be done by end of month.

@bkonyi would this also resolve the issue with: https://github.com/flutter/flutter/issues/17566 ?

@piotrpalek, yes it will, although behavior will likely be a bit different than it previously was as we can no longer share the UI isolate for callbacks for various reasons. Any communication with foreground UI will have to be established over isolate ports, MethodChannels, or any other method that doesn't rely on sharing memory with the main isolate.

Status update: both iOS and Android background execution changes are up for review and are still being iterated on. I expect the iOS changes in flutter/engine#5539 will be landing in the coming days, absent any requests for major modifications, and the Android changes in flutter/engine#5640 should hopefully be done next week after dealing with comments from the review. Thanks for your patience!

Awesome. Yeah, I had seen the PRs as they both reference this issue. You mentioned doing a sample plugin and I've seen the iOS one, will there be an Android sample? I'm guessing the Android alarm manager plugin could be updated once the changes go in

@MaikuB, yes, the AlarmManager plugin will be updated once flutter/engine#5640 lands and flutter/plugins#642 is complete.

Hello. Any update regarding this topic? Resolution was delayed to bucket7 milestone. Is it really gonna land there? This is crucial functionality for our project. Thanks for any response.

I unfortunately had to shift priorities for a few days, but I'm back to working on this now. We're _almost_ there, so thank you for being so patient!

Now that flutter/engine#5539, flutter/engine#5947, and flutter/engine#5954 have landed, all functionality needed for background execution on Android and iOS is implemented in the engine and should make it into the main Flutter repository during the next engine roll. Documentation and examples are in the works, and the android_alarm_manager plugin fix is up for review (flutter/plugins#642).

@bkonyi will android_alarm_manager also work on IOs now?

@ianldgs, unfortunately no. iOS doesn't provide any sort of mechanism for executing code on a periodic basis so it's likely not possible to create an iOS implementation (see this SO post). Often it's possible to achieve the same goals using one of the limited background execution modes (e.g., significant location changes, push notifications, Bluetooth state change, etc).

@bkonyi, will this fix an issue we're currently experiencing with not being able to execute native background tasks for an extended period (3 minutes) on iOS?

To clarify, here's our current issue...

Background:
Our app uses Bluetooth beacons to determine how much time someone spends a location. We've written all of our beacon code natively in AppDelegate.swift.

Issue:
Flutter appears to shut down our app after a few seconds when we're executing native code in the background after being woken up by a location event (region enter/exit in this case) even though we are extending our background execution time.

Why we think it's Flutter related:
We've tested our native beacon code with a native iOS app and have no problem consistently getting 180 seconds of background execution time.

What we've tried:
The only workaround we've had success with is putting a 30 seconds delay in the main() before runApp() when our app was launched in the background. However, this has been causing other issues.

Apologies, for the lengthy explanation, but this is a huge issue for us and we are trying to release in the next few weeks.

We're really hoping this fix will fix our issue as well.

Lastly, to be clear, we don't care so much about executing dart code in the background. Rather, our main concern is just not having Flutter prematurely terminate our app when woken up in the background.

Any help would be immensely appreciated.

Thanks!

@AndrewPetrovics unfortunately I don't think this will fix the issues you're seeing as these changes are primarily to allow for running Dart code from the background. I'm not super familiar with iOS background execution policies, but I'm actually working on a geofencing plugin for Android + iOS which sounds similar to your use case, so I'll keep an eye out for the issue you're having once I start the iOS portion today/tomorrow.

@chinmaygarde, would you happen to know anything about the issues @AndrewPetrovics is experiencing? Maybe this is worth filing a new issue for.

@bkonyi, sounds good. We ended up finding a workaround for the time being, but it's very hacky. I will create a separate issue when I get a chance.

Thanks!

@bkonyi May I ask, when will android_alarm_manager 0.2.0 be publicly deployed to pub.dartlang.org?

@ethael it should be available now, was just waiting to get permissions to publish the update.

Are there any examples or some documentation of this available?
Thanks!

@Solban there's two examples in the flutter/plugins repository:

I've also got a geofencing plugin in the works which has both Android (Kotlin) and iOS (Obj-C) support, but I'm not sure if that's going to live in flutter/plugins or not.

Here's some useful documentation for background execution related functionality:

  • The PluginUtilities class for passing callbacks between isolates
  • The IsolateNameServer which is useful for registering SendPort objects with Flutter for other isolates to lookup (this appears to be missing actual documentation, but the interface is rather straight forward).
  • The FlutterNativeView which is used to spawn the background isolate for the plugin on Android
  • The FlutterHeadlessDartRunner which is used to spawn the background isolate for the plugin on iOS

Currently there's no formal documentation on writing plugins with background execution capabilities. However, there should be a Medium post on the Flutter blog popping up in the coming weeks which will walk through the process of designing, implementing, and using plugins which utilize background execution.

Is there any solution for continues background work? Only correct way to continuously execute some long running code in Android is Foreground service.
Use case example would be continues GPS location tracking.

@audkar currently there's no plugin that can handle continuous background work, but that doesn't mean it can't be done. A plugin utilizing the functionality I referenced above in combination with a foreground service (instead of the JobIntentService I used for the geofencing plugin) would work fine.

I'm currently porting my iOS / Android Background Geolocation / Geofencing SDK to Flutter. It will be called flutter_background_geolocation.

I've got about 5 days' experience with Dart / Flutter but I get it. It should be ready within 2 weeks (though docs will take a bit longer with Dart-specific examples).

This SDK is nearly 5 years old and supported full time. It was originally developed for Apache Cordova, then later ported to React Native and NativeScript. It works in pure native apps as well. Under the hood, it's the same core Obj-c + Java library used with each development platform.

The SDK was originally developed for tracking first-responders in disaster zones (eg: hurricanes, earthquakes) in an environment where the cell-network is likely destroyed. It had to continue tracking even if app was terminated or device rebooted. The plugin contains its own SQLite database and HTTP service for automatically uploading locations to your server. This is particularly important for Android in the case where the app has been terminated, leaving only the SDK's foreground-service running "headless".

:warning: This SDK is not designed for social apps. it's designed specifically for "fleet-tracking" use-cases (eg: taxi, delivery service, emergency response, jogging, etc).

Here's a brief demo video.

See the Philosophy of Operation.

Edit I'll also be porting another library as flutter_background_fetch, which will be included as a dependency of flutter_background_geolocation. This module will awaken an iOS / Android app in the background about every 15 min, providing 30s of background-time for you to perform periodic work. See the react-native version for more information.

Ok, I've published flutter_background_geolocation. There's probably still a few holes to plugin in the facade to the native libs and the examples in docs need to be translated from the React Native version.

@christocracy good news. what about background-fetch? any estimations regarding that one?

@ethael Fetch will come in about 2 more weeks. It's a very simple plugin.

@bkonyi I tried your location change plugin to experiment with background execution. It seems the dart callback executed from the headless runner cannot use other plugins, failing with MissingPluginException.

On Android, with the android_alarm_manager plugin you solved this issue with AlarmService.setPluginRegistrant(this); to internally register the plugins from the background service. But I don't see how to achieve the equivalent for iOS.

Is it currently possible to call other plugins from a headless runner on iOS? If so, how can we register plugins in that context?

@bkonyi This issue is not resolved and should be reopened. The AlarmManager seems like a workaround at best because it only supports timed events. Flutter needs something more generic, so you can listen for certain events like Bluetooth device in range, for example. And it needs to support iOS better. I understand that iOS is much more restrictive, but Flutter should support the things that are available to native programmers.

I was excited to start with Flutter, but it seems like there are a lot of issues like this that make it unusable for all but simpler apps. I expected more from Google, and I think it's unfair of them to expect developers to make plugins to fill in the major gaps they left.

@dude8604 Google isn't going to provide everything and yes it is up to 3rd party plugin developers (like me) to contribute plugins to the ecosystem. I'm bringing two in currently myself.

I've spent a lot of time with Cordova, React Native and NativeScript. After 2 weeks with Flutter, I think it's quite excellent, though there are certainly holes (a cross platform Map component, for example, which I'm sure I'll be contributing to in the near future.)

I'm a professional plugin developer specializing in background operation of iOS and Android (geolocation & geofencing, in particular) for the last 5 years. What would you like to know?

@christocracy I agree that there need to be third party plugins, but background execution or at least being able to register callback functions for certain events seems like something an app framework should provide. My issue isn't with having to make plugins to extend the core functionality, but with releasing a framework that's missing basic features and expecting developers to volunteer their time to a for-profit company to fill in the gaps. Anyway, this isn't the right place to discuss this.

I want to run a background service and read certain events, process and possibly record the data, and if appropriate create a notification which will launch the main app if pressed. Some examples of the events would be: new Bluetooth device in range, incoming data on a socket, incoming data from a USB device, SMS received, GPS location changed, Bluetooth device connection attempt, a certain physical button is pressed, accelerometer data exceeds a specified value, if the main app is terminated, and a lot of other things I'm not thinking of. If someone could make a comprehensive plugin (with a free or open source license) for this that works on iOS and Android, I think this issue could be closed. And I would be eternally grateful that I can start developing with Flutter.

@dude8604 I think I know what you want. To do much of this obviously requires a foreground-service, with its required persistent notification. The user is aware of your running service.

Contact me via my github profile.

Consider that React Native was basically like "you get buttons, text fields and a list view, the rest is up to you" and it grew into what it is now because of the community. Google cannot possibly handle all implementations and its insane to think that the Flutter team will be able to replicate all functionality provided by both Android and iOS when those functions are being added by teams 100x (10,000x?) the size of Flutter.

The android_alarm_manager and image_picker doesn't seems to work (if both installed) after implementing it to a new project running Flutter 0.8.3-pre.47. The app forces to close. The example is working so I copied everything in the example and setup my firebase but still not working.

To add the issue @deckerst has raised, I'm not sure that it's appropriate to consider this closed when there isn't parity across Android and iOS with regards to being able to execute code that uses other plugins

Edit: just noticed there's another issue to track this

Just so this article is referenced here for those that have not seen it:
https://medium.com/flutter-io/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124

Thanks @slightfoot. Did see that and that's where I found the ticket (#21925) for getting iOS headless execution to work with plugins. Having a reference between these two tickets would've been useful.

On a related note, is there a plan to have headless execution included in the official documentation e.g. as part of the cookbook? I'd assume so but thought it's worth asking given there's likely a larger part of the community out that wouldn't know to check medium

Good point @MaikuB, added a doc bug for this!

Background-Support in flutter directly, see https://www.youtube.com/watch?v=_LfjILXswJs

I don't quite understand. If Flutter now supports background execution, why does the tutorial have mostly platform specific code?

Get Outlook for Androidhttps://aka.ms/ghei36


From: tonka notifications@github.com
Sent: Friday, September 21, 2018 3:39:28 AM
To: flutter/flutter
Cc: Philip Weiss; Mention
Subject: Re: [flutter/flutter] Flutter should provide an abstraction for background execution (#3671)

Background-Support in flutter directly, see https://www.youtube.com/watch?v=_LfjILXswJs


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/flutter/flutter/issues/3671#issuecomment-423490126, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ABWxFrGMGvfFtwkf025Q2Je6lUTZu2aPks5udMHggaJpZM4IVsUk.

@dude8604 the tutorial is for plugin developers who wish to developer a plugin to perform some particular background operation.

Consumers of some particular plugin are blind (as much as possible) to the platform-specific implementations.

So as a Consumer is there a way to run arbitrary code in the background, if there isn't a plugin for my specific use case?


From: Chris Scott notifications@github.com
Sent: Saturday, September 22, 2018 5:43:16 PM
To: flutter/flutter
Cc: Philip Weiss; Mention
Subject: Re: [flutter/flutter] Flutter should provide an abstraction for background execution (#3671)

@dude8604https://github.com/dude8604 the tutorial is for plugin developers who wish to developer a plugin to perform some particular background operation.

Consumers of some particular plugin are blind (as much as possible) to the platform-specific implementations.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/flutter/flutter/issues/3671#issuecomment-423783230, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ABWxFhmlurQ08wWXLmMvE3E6yQ_lYvS1ks5udtkkgaJpZM4IVsUk.

@dude8604 No.

As far as I'm currently aware:

You don't get to "run arbitrary code in the background". Android is strict now. iOS always has been.

@dude8604, @christocracy is correct. The background execution functionality demonstrated in the Medium article is targeted towards developers who want to create plugins that can execute Dart code in the background. Most Flutter users won't ever have to write platform specific code for background execution unless there isn't an existing plugin that matches their use case as these plugins will abstract away platform specific code behind a Dart interface.

The android_alarm_manager and image_picker doesn't seems to work (if both installed) after implementing it to a new project running Flutter 0.8.3-pre.47. The app forces to close. The example is working so I copied everything in the example and setup my firebase but still not working.

@rupert2133 would you mind filing an issue with more information? Feel free to mention me so I'm notified. This issue was for the broader requirement for background execution of Dart code and is closed, so any additional responses here are likely to get buried.

The android_alarm_manager and image_picker doesn't seems to work (if both installed) after

That reminds me. Yesterday while implementing Headless Android in my plugin, I had an error coming from googlemaps here.

When all the plugins are re-registered in the Headless state, registrar.activity() == null.

I had to manually hack that to get my app booting:

public static void registerWith(Registrar registrar) {
    final GoogleMapsPlugin plugin = new GoogleMapsPlugin();
+    Activity activity = registrar.activity();
+    if (activity != null) {
      registrar.activity().getApplication().registerActivityLifecycleCallbacks(plugin);
      registrar
              .platformViewRegistry()
              .registerViewFactory(
                      "plugins.flutter.io/google_maps", new GoogleMapFactory(plugin.state, registrar));
+    }
  }

This is going to be a problem with a large number of plugins, I suspect.

I want to run a background service and read certain events, process and possibly record the data, and if appropriate create a notification which will launch the main app if pressed. Some examples of the events would be: new Bluetooth device in range, incoming data on a socket, incoming data from a USB device, SMS received, GPS location changed, Bluetooth device connection attempt, a certain physical button is pressed, accelerometer data exceeds a specified value, if the main app is terminated, and a lot of other things I'm not thinking of. If someone could make a comprehensive plugin (with a free or open source license) for this that works on iOS and Android, I think this issue could be closed. And I would be eternally grateful that I can start developing with Flutter.

@bkonyi So which of the above things can I currently do with existing plugins? Can I use AlarmManager to poll for these events? But AlarmManager doesn't work on iOS, right?

@dude8604 The best you'll get for periodic events on iOS is via the "background-fetch" API. I'll be porting this plugin to flutter soon.

The iOS "Background Fetch" API will awaken a sleeping app in the background about every 15min (this is the fastest possible interval) providing your app exactly 30s of background running time. However, iOS uses machine-learning (presumably) and will throttle this based upon time-of-day and frequency of device / app usage (eg: at night, when user is presumably sleeping, fetch events might come once / hour.

@christocracy @bkonyi So all of these and their Android equivalents could be made into a plugin? How can I make a feature request for this?

@dude8604 You can't just wave a magic wand and *poof*. You go put on your work gloves and make it yourself. If you can't make it yourself, you find someone who can and you pay them tens-of-thousands of dollars.

@christocracy You're right, but I was hoping one of the largest corporations in the world would have the resources to develop a fully featured product and not require its users to spend tens of thousands of dollars to make it usable enough.

Well, yeah it's a large corporation.

Said corporation is also made up of individuals, who are not omnipresent. No framework can ever cover everything out-of-the-box, because if you try your project is going to turn into a pile of burning...well, trash.
There are hundreds of platform-specific APIs and no single team is going to cover them. You'll have to bind some yourself.

@dude8604 Consider that your definition of "fully featured" is not the same as mine. Their responsibility is to handle the intersection.

1 f you write this

Do we have a clear direction from docs? I saw Release Preview 2 saying that it has support for background execution. Some examples would be good to go.

@Pushan-Gupta background-execution is a plugin-specific thing.

It depends what you want to do. Track location? Receive push notifications? Monitor geofences? Detect BT devices? Beacons? Play music?

There’s no “one ring to rule them all support for background execution”

@christocracy Sorry I didn't know that. I was aiming for a specific thing. Say I want to make some posts request from the app. But the connection is off. As soon as the device comes back online, no matter if the app is open or not, the queue of those posts requests must be processed.

Example: Whatsapp enqueues messages before sending them to the server. If the device is offline it stores the queue and services it as soon as it comes online.

BTW I have a PR going, discussing plugin registration for background Isolates. If anyone has any thoughts...

https://github.com/flutter/engine/pull/6396

What's the point of FlutterHeadlessDartRunner currently?
I've implemented background execution on Android currently (no plugin just FlutterNativeView(ctx, true)), and that's was somewhat easy to do.
But on iOS it's just crashing

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
    let headless = FlutterHeadlessDartRunner.init()
    headless.run(withEntrypoint: "main") // just EXC_BAD_ACCESS here
}

Hey,
Please help in reminder app in flutter ios

@MohdLucky And the help you need is..?

@christocracy do you have update on implementation state of background_fetch plugin please?

not update on implementation state of background_fetch plugin , please provide some sample code for
running background notification.

Any update on this...I really thought that this is part of flutter :( ..this is than pretty much same issues than other web hybrid solutions have...

@radvansky-tomas I don't know why people just don't get that this is not within flutters responsibility. Even if you have to implement background execution natively you still have the advantage of one single code base. Writing one flutter plugin that does your background work takes merely one or two days of work. I had the same issue, I needed an android service that would be capable of playing music for me. I just wrote it in kotlin, implemented the communication layer using flutter and later on did the same for iOS.
It's entirely possible to just use the systems native background systems.
Instead of whining around here that X is not implemented,you can literally implement it without any problems whatsoever using the ecosystem provided by the team.

@SirWindfield Unfortunately you dont know what are you talking about. This is essential part of architecture, not plugin itself.

Flutter is presented as cross-platform solution producing native code, ie there is expectation that it can run code in its language (Dart) everytime when OS allows it.

So, if app is running after remote notification is received, and you can place breakpoint in existing native code, you should be able to call your flutter/dart code where are your services, models and finally UI.

To make it in your case...lets say that your music is playing in background and then you finish your playlist...after 10mins is your app shutdown. Then you call siri, or use headphones to start playback again of your app, whatever entry point you chose...native code is executed, but not its UI, your flutter code is not initialised and your lost as I am with my notifications.

So no its not possible, I can write native plugin catching notification for me, but then I need access to flutter business logic to process data, in my case crypto decrypt and releasing local notification with decrypted content

We'll, I've tested it on my phone extensively and it works without problems whatsoever.
It might be that my phone never killed the app though. My bad then.

@christocracy any update regarding background_fetch plugin Chris?

@ethael Here's the empty repo for you to watch for updates.
https://github.com/transistorsoft/flutter_background_fetch

@radvansky-tomas you can handle background events in Dart code by creating a background isolate as described in this Medium post on background execution. You'll likely need to write some native code for each platform to suit your particular needs unless there's a plugin that already exists which does what you want (unlikely, since I'm unaware of many plugins which support background execution at the moment).

@bkonyi Thank you for reply, I started to change firebase_messaging plugin to support background execution...but this issue is more about some generic way to do it. I mean it should be part of template = runner and its dart side where devs can execute such headless code, some rules, pattern standard as now is all over some blogs, suggestions etc.

Some initial work done: https://github.com/radvansky-tomas/plugins/tree/master/packages/firebase_messaging

Following some guides from https://github.com/bkonyi/FlutterGeofencing

I should finish it by end of this week, I am only working on iOS bits for now. Example project is using local notification plugin to show that message was received in background (silent notification) and then release new local one, to manifest success.

Some initial work done: https://github.com/radvansky-tomas/plugins/tree/master/packages/firebase_messaging

Following some guides from https://github.com/bkonyi/FlutterGeofencing

I should finish it by end of this week, I am only working on iOS bits for now. Example project is using local notification plugin to show that message was received in background (silent notification) and then release new local one, to manifest success.

@goderbauer and I were actually looking to add this support, but we would be more than happy to help you out with design and reviews if you plan on making a pull request.

So I pretty much finished that part, so now I can receive silent push notifications and my callback written in dart is executed while app is in background.

However, I cannot access any other plugin there. Callback has to be root/static method and really dont get how to call anything from there.

So I tried to make simple test, to use flutter local notification plugin to send local notification after silent one is received, but plugin seems to be not accessible (not registered?)

I found similar posts here: https://github.com/flutter/engine/pull/6396

Is there any other necessary step, which i have to do to load those plugins ?

My root level callback:
void callback(FirebaseMessage m, MessageEvent e) async { print('Message $m Event: $e'); final SendPort send = IsolateNameServer.lookupPortByName('messaging_send_port'); send?.send(e.toString()); }

Question is not how to access all dart code + plugins from that callback...query firestore, etc

My Background Fetch implementation is finally released.
background_fetch

@christocracy You're right, but I was hoping one of the largest corporations in the world would have the resources to develop a fully featured product and not require its users to spend tens of thousands of dollars to make it usable enough.

That's so true. If you get people's time you should give something back to them. If not then don't make these fancy marketing titles!

It seems like this issue is still causing folks woes? It's closed and has a lot of comments, so it's unlikely we're going to make many concrete project changes from this issue. :( (We'll need to file new ones to make more progress I expect.)

I would be very interested in us documenting the concrete changes desired here. Sounds like more background examples are desired? (e.g. https://github.com/flutter/flutter/issues/23794)

In any case, we'd love to have individual issues filed with individual asks. As others have noted above, Flutter is a large and complex project, and although we have a large (and rapidly expanding) team here at Google, we still just don't have enough engineers working fulltime on Flutter to answer all issues simultaneously. Flutter is 100% open source and all of our issues are on GitHub. Patches are always welcome of course. :)

For any with issues/changes desired, please file new issues to let all contributors know how we can help further: https://github.com/flutter/flutter/issues/new

Thanks!

@eseidel challenge accepted: #24278

I was hoping to avoid writing device specific code and having a Flutter Dart API implementation maybe based on events that would hide device and os specifications and specific implementation.

already solveda at here

@Krunal79-flutter how exactly, that approach would still have same issues. Thing is that in your scenario is flutter already initialised and its not proper background access then. Issue what I had and have, is when app is actually dead and silent notification (or app extension) will wake up your app and you need perform "dart" logic while flutter is not running yet (ie no UI present).

This really ought to be a much higher priority issue for whoever is managing the Flutter team. Implementing background functionality is a huge pain for the average Flutter developer and it breaks down often an in non-trivial ways. And I am sure that a lot of app developers are currently struggling with this.

@tomoerlemans010 please see the comment in https://github.com/flutter/flutter/issues/3671#issuecomment-438113161.

This particular issue is closed, please add comments to other open issues related to background execution or create a new one with the issues that you are facing.

Was this page helpful?
0 / 5 - 0 ratings