Flutter 封装:最佳实践 —— AppLifecycleState 状态监听封装

一、需求来源

项目中多页面需要同时监听 AppLifecycleState 根据状态实现不同的业务逻辑;尝试多种实现,使用起来比较麻烦,为了开发效率,随封装一个。代码不复杂,核心在于极简的封装方法。

效果如下:

csharp 复制代码
[log] 2024-01-20 11:04:36.473511 MyHomePage onInactive
[log] 2024-01-20 11:04:36.476352 AppLifecycleStateObserverDemo onInactive
[log] 2024-01-20 11:04:37.189494 MyHomePage onPause
[log] 2024-01-20 11:04:37.190003 AppLifecycleStateObserverDemo onPause
[log] 2024-01-20 11:04:41.896665 MyHomePage onInactive
[log] 2024-01-20 11:04:41.896964 AppLifecycleStateObserverDemo onInactive
[log] 2024-01-20 11:04:42.177396 MyHomePage onResume
[log] 2024-01-20 11:04:42.178090 AppLifecycleStateObserverDemo onResume

// MyHomePage 为主页面;
// AppLifecycleStateObserverDemo 为特定业务界面;

二、使用示例

dart 复制代码
import 'package:flutter/material.dart';
import 'package:flutter_templet_project/util/AppLifecycleObserver.dart';
import 'package:flutter_templet_project/util/debug_log.dart';

class AppLifecycleStateObserverDemo extends StatefulWidget {

  AppLifecycleStateObserverDemo({
    super.key, 
    this.title
  });

  final String? title;

  @override
  State<AppLifecycleStateObserverDemo> createState() => _AppLifecycleStateObserverDemoState();
}

class _AppLifecycleStateObserverDemoState extends State<AppLifecycleStateObserverDemo> with
    WidgetsBindingObserver,
    AppLifecycleObserverMixin {

  final _scrollController = ScrollController();


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title ?? "$widget"),
        actions: ['done',].map((e) => TextButton(
          child: Text(e,
            style: TextStyle(color: Colors.white),
          ),
          onPressed: () => debugPrint(e),)
        ).toList(),
      ),
      body: buildBody(),
    );
  }

  buildBody() {
    return Scrollbar(
      controller: _scrollController,
      child: SingleChildScrollView(
        controller: _scrollController,
        child: Column(
          children: [
            Text("$widget"),
          ],
        ),
      ),
    );
  }

  /*************** AppLifecycleObserverMixin ***************/
  
  @override
  Future<void> onResume() async {
    // TODO: implement onResume
    DDLog("$widget onResume");
  }

  @override
  Future<void> onInactive() async {
    // TODO: implement onInactive
    DDLog("$widget onInactive");
  }

  @override
  Future<void> onPause() async {
    // TODO: implement onPause
    DDLog("$widget onPause");
  }

  @override
  Future<void> onDetached() async {
    // TODO: implement onDetached
    DDLog("$widget onDetached");
  }
}

三、源码

1、AppLifecycleObserver 源码

dart 复制代码
/// app 前后台生命周期函数监听
class AppLifecycleObserver extends WidgetsBindingObserver{

  AppLifecycleObserver({
    required this.onResume,
    required this.onInactive,
    required this.onPause,
    required this.onDetached,
    this.data,
  });

  final AsyncCallback onResume;
  final AsyncCallback onInactive;
  final AsyncCallback onPause;
  final AsyncCallback onDetached;
  final dynamic data;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // DDLog('${Get.currentRoute} APP状态监听:$state, ${data ?? ""}');

    switch (state) {
      case AppLifecycleState.resumed:
        onResume();
        break;
      case AppLifecycleState.inactive:
        onInactive();
        break;
      case AppLifecycleState.paused:
        onPause();
        break;
      case AppLifecycleState.detached:
        onDetached();
        break;
    }
  }
}

2、AppLifecycleObserverMixin 源码

dart 复制代码
/// app 前后台生命周期函数混入封装
mixin AppLifecycleObserverMixin<T extends StatefulWidget> on State<T>, WidgetsBindingObserver{
  late final _lifecycleEvent = AppLifecycleObserver(
    onResume: onResume,
    onInactive: onInactive,
    onPause: onPause,
    onDetached: onDetached,
  );

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

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

  Future<void> onResume() async {
    throw UnimplementedError("❌: $this 未实现 onResume");
  }

  Future<void> onInactive() async {
    throw UnimplementedError("❌: $this 未实现 onInactive");
  }

  Future<void> onPause() async {
    throw UnimplementedError("❌: $this 未实现 onPause");
  }

  Future<void> onDetached() async {
    throw UnimplementedError("❌: $this 未实现 onDetached");
  }

}

四、总结

1、使用 AppLifecycleObserverMixin 需要同时遵循 WidgetsBindingObserver
scala 复制代码
class _AppLifecycleStateObserverDemoState extends State<AppLifecycleStateObserverDemo> with
    WidgetsBindingObserver,
    AppLifecycleObserverMixin {
2、AppLifecycleObserverMixin 生命周期方法是一组,即使不使用也要全部实现(考虑到未来排查错误);如果未实现会日志报错,提示到具体页面;

github

相关推荐
一天 24h3 分钟前
从单体到分布式:JWT 如何彻底改变 Web 认证系统
前端·分布式
持梦远方3 分钟前
Nginx 静态资源挂载与前端部署实战笔记
linux·前端·笔记·nginx
木斯佳4 分钟前
前端八股文面经大全:腾讯云智前端一面(2026-05-13)·面经深度解析
前端·状态模式
fanzhonghong5 分钟前
javaWeb后端开发之Linux项目部署3和Docker部署1
linux·服务器·前端·docker
拉里呱唧6 分钟前
在线可视化HTML编辑器横评:8款拖拽式工具的实测对比
前端·编辑器·html
恋猫de小郭8 分钟前
Flutter 3.44 发布啦,超级大版本更新!!!
android·flutter·ios
lihaozecq9 分钟前
Agent 开发 Todo 机制设计,让 Agent 拥有规划能力
前端·agent·ai编程
lchcy18 分钟前
移动端h5好多兼容性问题啊
前端
KaMeidebaby23 分钟前
卡梅德生物技术快报|多肽库筛选:基于全质粒 PCR 的噬菌体文库构建与小分子表位淘选实战
前端·数据库·其他·百度·新浪微博
张3蜂25 分钟前
Flutter macOS 安装文档
flutter·macos