Flutter WidgetsBindingObserver 在 iOS 上的坑

Flutter 中我们要拿到生命周期的回调会使用 WidgetsBindingObserver.当我们启动的第一个 Widget 就使用到 WidgetsBindingObserver 时,其初始启动回调的执行时机在两个平台表现不一致, 而且在 iOS release 和 debug 两种模式下也会表现不一致。

我们用一个简单 Demo 来实验一下:

import 'package:flutter/widgets.dart';

class LifecycleWatcher extends StatefulWidget {
  const LifecycleWatcher({Key? key}) : super(key: key);

  @override
  State createState() => _LifecycleWatcherState();
}

class _LifecycleWatcherState extends State
    with WidgetsBindingObserver {
  AppLifecycleState? _lastLifecycleState;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
  }

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

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _lastLifecycleState = state;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_lastLifecycleState == null) {
      return const Text('This widget has not observed any lifecycle changes.');
    }
    return Text(
        'The most recent lifecycle state this widget observed was: $_lastLifecycleState.');
  }
}

void main() {
  runApp(
    const Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: LifecycleWatcher(),
      ),
    ),
  );
}

上面是简单的 WidgetsBindingObserver 使用,并且执行回调的 AppLifecycleState 显示在屏幕上。

  • flutter version 2.5.3 dart version 2.14.4 执行结果:

  • iOS15.0

    • debug 模式: 初始启动 didChangeAppLifecycleState 不会执行.
    • release 模式: 初次安装启动 didChangeAppLifecycleState 不会执行. 已安装后再重新启动执行 AppLifecycleState.resumed.
  • Android: debug 和 release 模式下初次启动 didChangeAppLifecycleState 都不会执行。

所以如果我们在启动第一个界面在 AppLifecycleState.resumed 里面做了一些事情,就要考虑到 iOS release 下初次启动就会调用一次而 Android 不会调用的差异。

还有一个注意点 AppLifecycleState.resumed 在 iOS 原生系统 Alert 弹窗关闭时也会调用,当我们程序首次启动时,可能会有很多系统的 Alert 弹窗,比如通知,网络等权限弹框,所以 App 启动时 AppLifecycleState.resumed 生命周期可能会触发多次。

你可能感兴趣的:(Flutter WidgetsBindingObserver 在 iOS 上的坑)