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

相关推荐
passer981几秒前
列表项切换时同步到可视区域
前端
FogLetter2 分钟前
移动端适配的终极奥义:从lib-flexible到postcss-pxtorem的全方位指南
前端·postcss
易元3 分钟前
设计模式-访问者模式
前端·后端·设计模式
兵临天下api4 分钟前
Elasticsearch 查询性能优化:从 3 秒到 300ms 的 6 个核心参数调优指南
前端
子林super12 分钟前
y1新建cluster集群redis
前端
Pedantic32 分钟前
swift 日期与时间的三个结构体
前端
南方kenny32 分钟前
Mock.js:前端开发的假数据神器
前端·javascript
芹丸子33 分钟前
vue cli 创建项目一直失败
前端
鹏程十八少37 分钟前
6.android Vivo手机 指纹解锁动画 (附源码)
前端
AliciaIr37 分钟前
深入理解React Hook:useRef的底层机制与高级应用
前端·react.js