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

相关推荐
溪饱鱼8 分钟前
第6章: SEO与交互指标
服务器·前端·microsoft
咔_19 分钟前
LinkedList详解(源码分析)
前端
逍遥德1 小时前
CSS可以继承的样式汇总
前端·css·ui
读心悦1 小时前
CSS3 选择器完全指南:从基础到高级的元素定位技术
前端·css·css3
_龙衣2 小时前
将 swagger 接口导入 apifox 查看及调试
前端·javascript·css·vue.js·css3
进取星辰3 小时前
25、Tailwind:魔法速记术——React 19 样式新思路
前端·react.js·前端框架
x-cmd4 小时前
[250512] Node.js 24 发布:ClangCL 构建,升级 V8 引擎、集成 npm 11
前端·javascript·windows·npm·node.js
夏之小星星4 小时前
el-tree结合checkbox实现数据回显
前端·javascript·vue.js
crazyme_64 小时前
前端自学入门:HTML 基础详解与学习路线指引
前端·学习·html
撸猫7914 小时前
HttpSession 的运行原理
前端·后端·cookie·httpsession