My app is connected to BLE accessory using CoreBluetooth state restoration and preservation (SRP) and is using bluetooth-central
Background Execution Mode. This means that the native part of the app written in Swift can receive HR samples continuously even when the app is in the background. However, what I can also see is that the Flutter part of the app keeps running despite app being in paused
lifecycle state.
I did a simple experiment and started timer in Flutter when using and not using Core Bluetooth SRP.
- when not using the SRP the Timer stopped printing into log after 20 seconds
- when using SRP the Timer kept running indefinitely as long as the BLE accessory was sending HR samples
What I'm looking for is to maintain the typical Flutter behavior but keep using SRP on the native side.
- Which part of the Flutter is responsible for stopping the "execution" when app goes to paused state?
- Can Flutter be paused despite SRP keeping the app awake (due to using
bluetooth-central
mode and receiving continuous HR updates)? - Is there a way to put Flutter engine to
paused
state programmatically? - If not, do you see any other ways to keep the typical Flutter engine/ViewController behavior?
The issue here is in some sort of misunderstanding. When the flutter part is
paused,
it doesn't mean it pauses its execution by default. You have to manually pause all the needed stuff when you go to this state.For the most "functional(non ui)" cases, those states
WidgetsBindingObserver
catches are mere 'indications' rather than 'actions'... This is especially applicable when you listen to something native part emitting in the background.Here is some explanation from the official documentation:
It means that the Flutter engine only skips drawing stuff on screen - all the other operations are active and will be active till the app's death. In the case of iOS, it may never happen till the explicit kill of the app. In Android, the OS can kill it in arbitrary time or not kill it - depending on the load of the OS itself.
To ignore any activity during the
paused
state, you have to explicitly and manually unsubscribe any listeners in thepaused
state and subscribe them once more in theresumed
state. I am saying words like 'subscribe' and 'unsubscribe' because I don't know the specifics of your code - you may easily just ignore all the events or something...If you want the flutter part not to function at all when the app is in the background, you have to kill the flutter part manually - you can do it if you established your flutter engine connection manually, not relying on
FluttFlutterViewController
,FlutterFragment
etc. You have to have control over the code in order to do that. Afterward, when your app is in the foreground once more(to know that you would have to rely on native callbacks since when the flutter engine is dead, there is no callback in dart code), you will be able to reestablish flutter infrastructure and run it once more.I don't recommend the latter approach since it is sooo redundant - ignoring events and/or subscribing/unsubscribing is sufficient in most cases. I think even including yours.
Hope it helps.