drift icon indicating copy to clipboard operation
drift copied to clipboard

[Question]: Shutdown isolate when app quit by swiping from recent items in Android

Open rohansohonee opened this issue 5 years ago • 9 comments

Hi @simolus3

I am starting the moor isolate on main thread as described in your documentation. The steps I have followed are as follows:

  1. Start isolate on main thread.
  2. Shutdown isolate in onWillPop i.e user quits app by pressing back button.
  3. Also manage shutdown of isolate when user quits app by swiping from recent items in android??

How to achieve step 3. If step 3 is not handled then the isolate continues running which is not good. Because if I open the app, it will start a brand new isolate. The only method is onWillPop. Do you know of a method that can detect android app quit??

Also is there a different approach on handling the shutdown case for isolates or is this implementation the way to go??

rohansohonee avatar Jan 03 '20 19:01 rohansohonee

I think Android terminates the whole app process after swiping it from recent items (unless you have a special setup with background processes / services). So to my best knowledge, an isolate started from the main thread will be terminated (so is the main thread). Since the process will be terminated, there is no reliant callback (and I don't think Flutter exposes onStop).

Something that's more reliable than onWillPop would be a WidgetsBindingObserver. You could listen for lifecycle events and terminate the isolate when the app reaches a paused state, and spawn the isolate when resumed (or as needed). Be aware that the app may reach a paused state without being terminated, for instance if a user temporarily switches to another app.

Note that a safe shutdown via shutdownAll or close is not required to maintain data integrity, just to clear up unnecessary resources. If the system shuts down your app, all resources will be freed either way. So while closing resources manually is definitely a good practice, it isn't strictly necessary here.

simolus3 avatar Jan 03 '20 19:01 simolus3

Something that's more reliable than onWillPop would be a WidgetsBindingObserver. You could listen for lifecycle events and terminate the isolate when the app reaches a paused state, and spawn the isolate when resumed (or as needed). Be aware that the app may reach a paused state without being terminated, for instance if a user temporarily switches to another app.

Unfortunately when user taps back button the paused state is not called. Thus I had to handle onWillPop to shutdown the isolate.

Also I am using WidgetsBindingObserver to detect lifecycle events such as paused and resumed.

unless you have a special setup with background processes / services

yes i do have a special setup. Can you provide a solution during this approach?? I would like to manually handle resources and don't want to depend on the system.

rohansohonee avatar Jan 03 '20 19:01 rohansohonee

Can there be a feature that allows me to check whether moor isolate is already running. This would help in avoiding moor isolate to start again if user opens app again?? Can this be done??

rohansohonee avatar Jan 03 '20 20:01 rohansohonee

Are you using the MoorIsolate from multiple isolates or just the main thread? If it's just the main thread, you could do something like

MoorIsolate _instance;

// call this whenever you need a moor isolate, don't create it anywhere else
Future<MoorIsolate> useIsolate() async {
  if (_instance != null) {
    return _instance;
  }
  return _instance = await MoorIsolate.spawn(...);
}

Future<void> shutdown() async {
  _instance?.shutdownAll();
  _instance = null;
}

simolus3 avatar Jan 03 '20 20:01 simolus3

Won't _instance be null when user swipes app from recent items and open's app again??

rohansohonee avatar Jan 03 '20 20:01 rohansohonee

I can't think of any scenario where the Flutter engine would terminate the main isolate but keep a background isolate running... If that happened there wouldn't be any way to detect whether a background isolate is running on the second app start (at least not from Dart).

You mentioned that you have a special setup, can you share more details? If your app doesn't run operations independent of UI (say with WorkManager or some geofencing), this shouldn't affect you.

simolus3 avatar Jan 03 '20 21:01 simolus3

I am using audio_service package for background audio. This runs it's own isolate. I was unable to send across my moor isolate instance to the audioservice isolate. Thus I am trying to keep moor isolate running as long as the UI is visible and then clean up resources when UI is not visible. Cleaning up moor isolate in applifecycle paused is wasteful because the isolate needs to be spawned again on resumed. This means if the user switches back and forth from the app I would be shutting down and again have to be starting the moor isolate. I would like shutting down of moor isolate in two ways:

  1. When user presses back button.
  2. When user swipes the app from recent item.

I have achieved 1, but 2 seems to be unachievable. 2 calls onTaskRemoved in android which cannot be detected in Flutter dart side. Thus it is impossible to shutdown the isolate.

Also if possible could you provide a solution where I can send moor isolate instance specifically to the audioservice isolate. Here is the link of audioservice https://github.com/ryanheise/audio_service

rohansohonee avatar Jan 04 '20 04:01 rohansohonee

Hi @simolus3

Can there be a mechanism where on app launch we first check if moor isolate is already running?? Is this possible??

rohansohonee avatar Jan 04 '20 08:01 rohansohonee

@rohansohonee

I have achieved 1, but 2 seems to be unachievable. 2 calls onTaskRemoved in android which cannot be detected in Flutter dart side. Thus it is impossible to shutdown the isolate.

I faced a similar issue, to solve this, I listen to the onDetachedFromEngine on the native side (Java), and send a message through the MethodChannel to the dart side, so I have a chance to do some cleanup on the dart side or kill the isolate.

Here's my code https://github.com/AgoraIO-Extensions/iris_method_channel_flutter/pull/75/files

littleGnAl avatar Aug 11 '23 05:08 littleGnAl