# 生命周期

本文作者:阳九五 (opens new window)

本站地址:https://blog.56321654.xyz (opens new window)

# StatefulWidget 生命周期

Image

  • 执行顺序,从上往下
名称 说明
createState 创建 State 只执行1次
initState 初始 State, mounted 等于 true, 只执行1次
didChangeDependencies 父或祖先widget中的InheritedWidget改变时会被调用
build UI 被重新渲染的时候多次执行
addPostFrameCallback 渲染结束回调,只执行1次
didUpdateWidget 父类 setState 后,子类就会触发
deactivate 从组件树中移除 State 时调用
dispose 组件被释放时调用

不要再 build 里面更新状态, 影响性能

# 说明

  • initState 初始状态数据

void initState() {
    super.initState();
    print("initState");
}
1
2
3
4
5
  • build 渲染视图,可多次

Widget build(BuildContext context) {
    return Column(
        children: [
            ElevatedButton(
                onPressed: () {},
                child: const Text("切换图片"),
            ),
            imageWidget(
                imgUrl: imgUrl ?? img1,
            ),
        ],
    );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • mounted 状态

flutter 分配完你的组件树位置,会设置 mountedtrue.
你需要在 mounted == true 情况下,调用 setState() 来更新 UI ,这才是安全的操作。

ElevatedButton(
    onPressed: () {
        if (mounted == true) {
            setState(() {
                imgUrl = imgUrl == img1 ? img2 : img1;
            });
        }
    },
    child: const Text("切换图片"),
),
1
2
3
4
5
6
7
8
9
10
  • didChangeDependencies

父或祖先widget中的InheritedWidget改变时会被调用。

InheritedWidget和 React 中的 context 功能类似,和逐级传递数据相比,它们能实现组件跨级传递数据。

这种从根开始向下传递数据的方式,很适合做全局数据的管理,如样式、基础数据等。

  // 父或祖先widget中的InheritedWidget改变时会被调用

void didChangeDependencies() {
    super.didChangeDependencies();
    print("didChangeDependencies");
}
1
2
3
4
5
6
  • didUpdateWidget

父类 setState 后,子类就会触发

// 父类 setState 后,子类就会触发

void didUpdateWidget(oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget");
}
1
2
3
4
5
6
  • addPostFrameCallback

渲染结束回调,只执行1次
如我们可以放在 initState 时设置

// 需要引用 SchedulerBinding
// 初始 State, mounted 等于 true, 只执行1次

void initState() {
    super.initState();
    print("initState");

    // 渲染结束调用,只执行1次
    SchedulerBinding.instance?.addPostFrameCallback((timeStamp) {
    print("addPostFrameCallback");
    print(timeStamp);
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  • deactivate

从组件树中移除 State 时调用


void deactivate() {
    super.deactivate();
    print("deactivate");
}
1
2
3
4
5
  • dispose

组件被释放时调用


void dispose() {
    print("dispose");
    super.dispose();
}
1
2
3
4
5

# 代码

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

void main() {
  runApp(const MyApp());
}

const img1 =
    "https://ducafecat.tech/2021/12/09/blog/2021-jetbrains-fleet-vs-vscode/2021-12-09-10-30-00.png";
const img2 =
    "https://ducafecat.tech/2021/12/09/blog/2021-jetbrains-fleet-vs-vscode/2021-12-09-20-45-02.png";

Widget imageWidget({required String imgUrl}) {
  return Container(
    padding: const EdgeInsets.all(10),
    color: Colors.amber,
    child: Image.network(imgUrl),
  );
}

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

  // 创建 State 只执行1次
  
  State<BannerWidget> createState() {
    print("createState");
    return _BannerWidgetState();
  }
}

class _BannerWidgetState extends State<BannerWidget> {
  String? imgUrl;

  // 初始 State, mounted 等于 true, 只执行1次
  
  void initState() {
    super.initState();
    print("initState");

    // 渲染结束调用,只执行1次
    SchedulerBinding.instance?.addPostFrameCallback((timeStamp) {
      print("addPostFrameCallback");
      print(timeStamp);
    });
  }

  // 父或祖先widget中的InheritedWidget改变时会被调用
  
  void didChangeDependencies() {
    super.didChangeDependencies();
    print("didChangeDependencies");
  }

  // 父类 setState 后,子类就会触发
  
  void didUpdateWidget(oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget");
  }

  // 从组件树中移除 State 时调用
  
  void deactivate() {
    super.deactivate();
    print("deactivate");
  }

  // 组件被释放时调用
  
  void dispose() {
    print("dispose");
    super.dispose();
  }

  // UI 被重新渲染的时候多次执行
  
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: () {
            if (mounted == true) {
              setState(() {
                imgUrl = imgUrl == img1 ? img2 : img1;
              });
            }
          },
          child: const Text("切换图片"),
        ),
        imageWidget(
          imgUrl: imgUrl ?? img1,
        ),
      ],
    );
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: const [
            Text('有无状态组件'),
            BannerWidget(),
          ],
        ),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
flutter: createState
flutter: initState
flutter: didChangeDependencies
flutter: addPostFrameCallback
flutter: 0:00:00.000000
1
2
3
4
5

# StatelessWidget 生命周期

无状态组件,不需要处理生命周期,直接显示即可

abstract class StatelessWidget extends Widget {
  /// Initializes [key] for subclasses.
  const StatelessWidget({ Key? key }) : super(key: key);

  /// Creates a [StatelessElement] to manage this widget's location in the tree.
  ///
  /// It is uncommon for subclasses to override this method.
  
  StatelessElement createElement() => StatelessElement(this);
  ...
1
2
3
4
5
6
7
8
9
10

在源码中可见 createElement() 创建组件到组件树,不需要重写去维护

# App生命周期

  • 第一步: 创建 StatefulWidget 组件,混入 WidgetsBindingObserver
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  ...
1
2
  • 第二步:添加观察者 addObserver

void initState() {
    super.initState();
    WidgetsBinding.instance?.addObserver(this); //添加观察者
}
1
2
3
4
5
  • 生命周期变化时回调 didChangeAppLifecycleState
//  生命周期变化时回调

void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print("didChangeAppLifecycleState: $state");
}
1
2
3
4
5
6
名称 说明
resumed 应用程序可见且响应用户输入
inactive 应用程序处于非激活状态,无法响应用户输入
pause 应用程序不可见且无法响应用户输入,运行在后台
detached 应用程序仍寄存在Flutter引擎上,但与平台 View 分离
suspending 应用被挂起,此状态IOS永远不会回调

# 代码

import "package:flutter/material.dart";

void main() {
  runApp(const MyApp());
}

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

  
  _MyAppState createState() => _MyAppState();
}

//实现WidgetsBindingObserver观察者
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addObserver(this); //添加观察者
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("App生命周期"),
        ),
        body: Column(
          children: <Widget>[
            const Text("首页"),
          ],
        ),
      ),
    );
  }

  //  生命周期变化时回调
  //  resumed:应用可见并可响应用户操作,app进入前台
  //  inactive:用户可见,但不可响应用户操作,比如来了个电话,前后台切换的过渡状态
  //  paused:已经暂停了,用户不可见、不可操作,app进入后台
  //  suspending:应用被挂起,此状态IOS永远不会回调
  
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print("didChangeAppLifecycleState: $state");
  }

  //当前系统改变了一些访问性活动的回调
  
  void didChangeAccessibilityFeatures() {
    super.didChangeAccessibilityFeatures();
    print("didChangeAccessibilityFeatures");
  }

  //低内存回调
  
  void didHaveMemoryPressure() {
    super.didHaveMemoryPressure();
    print("didHaveMemoryPressure");
  }

  //用户本地设置变化时调用,如系统语言改变
  
  void didChangeLocales(List<Locale>? locale) {
    super.didChangeLocales(locale);
    print("didChangeLocales");
  }

  //应用尺寸改变时回调,例如旋转
  
  void didChangeMetrics() {
    super.didChangeMetrics();
    Size? size = WidgetsBinding.instance?.window.physicalSize;
    print("didChangeMetrics  :宽:${size?.width} 高:${size?.height}");
  }

  //系统切换主题时回调
  
  void didChangePlatformBrightness() {
    super.didChangePlatformBrightness();
    print("didChangePlatformBrightness");
  }

  ///文字系数变化
  
  void didChangeTextScaleFactor() {
    super.didChangeTextScaleFactor();
    print(
        "didChangeTextScaleFactor  :${WidgetsBinding.instance?.window.textScaleFactor}");
  }

  
  void dispose() {
    super.dispose();
    WidgetsBinding.instance?.removeObserver(this); //销毁观察者
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
flutter: didChangeMetrics  :宽:1125.0 高:2436.0
flutter: didChangeAppLifecycleState: AppLifecycleState.inactive
flutter: didHaveMemoryPressure
flutter: didChangeAppLifecycleState: AppLifecycleState.paused
flutter: didChangePlatformBrightness
flutter: didChangeMetrics  :宽:1125.0 高:2436.0
flutter: didChangePlatformBrightness
flutter: didChangeMetrics  :宽:1125.0 高:2436.0
flutter: didChangeAppLifecycleState: AppLifecycleState.inactive
flutter: didChangeAppLifecycleState: AppLifecycleState.resumed
1
2
3
4
5
6
7
8
9
10
最近更新: 7/29/2025, 9:40:27 AM