About application lifecycle

Our application uses SystemChannels.lifecycle.setMessageHandler to detect lifecycle events (e.g., transitioning from background to foreground) and invoke appropriate methods.

We have noticed that, on some iOS devices, the AppLifecycleState.resumed state is being detected even when restarting the app after it was previously terminated. However, this behavior differs depending on the iOS device. For example, on an iPhone X (iOS 16.5.1), the resumed state is not detected upon restarting the app, but on an iPhone 13 (iOS 18.5), the resumed state is detected.

What could be causing this discrepancy?

If anyone has information or insight about this, we would greatly appreciate your help.

Thank you for reading.

I may not be able to clear the things here but I noticed something strange too. We have a class that is pretty basic lifecycle tracker

class _AppLifecycleHandlerState extends State<AppLifecycleHandler>
    with WidgetsBindingObserver, AutomaticKeepAliveClientMixin<AppLifecycleHandler> {
//...
  @override
  void initState() {
    super.initState();
    log.i('Creating AppLifecycleHandler');
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

While logging the state transitions I can see this on iPhone:

2025-06-11T07:22:51.332962Z +29924 I [AppLifecycleHandler] App state changed to AppLifecycleState.inactive, last action was 2025-06-11 08:13:00.399797
2025-06-11T07:22:52.240255Z +29925 I [AppLifecycleHandler] App state changed to AppLifecycleState.hidden, last action was 2025-06-11 08:13:00.399797
2025-06-11T07:22:52.240356Z +29925 I [AppLifecycleHandler] App state changed to AppLifecycleState.paused, last action was 2025-06-11 08:13:00.399797
...
2025-06-11T09:03:29.877291Z +35963 I [AppLifecycleHandler] App state changed to AppLifecycleState.hidden, last action was 2025-06-11 08:22:52.240363
2025-06-11T09:03:29.879380Z +35963 I [AppLifecycleHandler] App state changed to AppLifecycleState.inactive, last action was 2025-06-11 08:22:52.240363
2025-06-11T09:03:30.199188Z +35963 I [AppLifecycleHandler] App state changed to AppLifecycleState.resumed, last action was 2025-06-11 08:22:52.240363

Which means that when user leaves the app (without terminating), the states go through inactive, hidden to paused. And then when coming back it’s hidden, inactive, resumed.

For me it’s quite confusing and it’s worth remembering that multiple states are emitted very quickly.


Back to your question.

The fact that you’re not receiving the resumed transition on launch may be related to when you are subscribing to the WidgetsBindingsObserver/SystemChannels. In my case when I create my AppLifecycleHandler I don’t get any notifications, so I rely on my initState/constructor to determine the app launch. My widget stays at the top of the widget tree, so once the runApp() is executed this widget is instantiated and I only receive updates after it’s built.