🦋 Flutter Widget 生命周期

源码级别深度解析

核心文件:framework.dart + binding.dart
2026-03-03 | 每日技术深度解读

📚 目录

1️⃣ Widget/Element/State 三棵树

2️⃣ Widget 基类解析

3️⃣ StatelessWidget

4️⃣ StatefulWidget

5️⃣ State 生命周期详解

6️⃣ 关键回调方法

7️⃣ Element 类型体系

8️⃣ BuildOwner 机制

9️⃣ WidgetsBinding

🔟 最佳实践

🌳 Widget/Element/RenderObject 三棵树

核心概念:Flutter 通过三棵树协作完成 UI 渲染

Widget 树

配置信息(不可变)

轻量级,频繁重建

Element 树

Widget 的实例化

管理生命周期

RenderObject 树

实际渲染、布局、绘制

🎯 Widget 基类

@immutable abstract class Widget extends DiagnosticableTree { const Widget({this.key}); final Key? key; /// 创建 Element @protected @factory Element createElement(); /// 判断是否可以更新 static bool canUpdate(Widget oldWidget, Widget newWidget) { return oldWidget.runtimeType == newWidget.runtimeType && oldWidget.key == newWidget.key; } }

关键点:Widget 是不可变的配置描述

📦 StatelessWidget

abstract class StatelessWidget extends Widget { const StatelessWidget({super.key}); @override StatelessElement createElement() => StatelessElement(this); /// 构建 Widget 树 @protected Widget build(BuildContext context); }

特点:

  • 无内部状态
  • build() 依赖外部参数
  • 父 Widget 重建时会重新 build

🔧 StatefulWidget

abstract class StatefulWidget extends Widget { const StatefulWidget({super.key}); @override StatefulElement createElement() => StatefulElement(this); /// 创建 State 对象 @protected @factory State createState(); }

特点:

  • Widget 本身不可变
  • State 持有可变状态
  • State 对象在 Element 生命周期内持久

🔄 State 生命周期

enum _StateLifecycle { created, // createState 后 initialized, // initState 后 ready, // didChangeDependencies 后 defunct, // dispose 后 }

生命周期回调:

initState → didChangeDependencies → build → didUpdateWidget → deactivate → dispose

1️⃣ initState()

调用时机:State 对象被插入树时,只调用一次

@protected @mustCallSuper void initState() { assert(_debugLifecycleState == _StateLifecycle.created); }

用途:

  • 初始化状态变量
  • 订阅 Stream/ChangeNotifier
  • 初始化 AnimationController

2️⃣ didChangeDependencies()

调用时机:initState 后立即调用,依赖变化时再次调用

典型场景:

  • InheritedWidget 变化
  • Theme/Locale/MediaQuery 变化
  • 调用 dependOnInheritedWidgetOfExactType 后

注意:在此方法中可以安全使用 context 获取 InheritedWidget

3️⃣ build()

调用时机:需要渲染时,可能被多次调用

@protected Widget build(BuildContext context);

触发条件:

  • 首次插入树
  • 调用 setState()
  • 父 Widget 重建
  • InheritedWidget 变化

原则:build 应该是纯函数,无副作用

⚡ setState()

void setState(VoidCallback fn) { assert(() { if (_element == null) { throw FlutterError( 'This widget has been unmounted...' ); } return true; }()); fn(); // 执行状态修改 _element!.markNeedsBuild(); // 标记需要重建 }

流程:

1. 执行回调修改状态

2. 调用 Element.markNeedsBuild()

3. BuildOwner 调度重建

4️⃣ didUpdateWidget()

@mustCallSuper @protected void didUpdateWidget(covariant T oldWidget) {}

调用时机:父 Widget 用相同 key 和 runtimeType 重建时

用途:

  • 比较新旧 Widget 配置
  • 响应属性变化启动动画
  • 重新订阅新的 Stream

5️⃣ deactivate()

调用时机:Element 从树中移除,但可能被重新插入

场景:

  • Widget 被 GlobalKey 移动位置
  • 条件渲染导致 Widget 消失
  • 列表项被移除

注意:可能不会立即 dispose,同一帧内可能被重新插入

6️⃣ dispose()

调用时机:State 对象永久移除,生命周期结束

必须释放:

  • AnimationController.dispose()
  • TextEditingController.dispose()
  • StreamSubscription.cancel()
  • Timer.cancel()

警告:dispose 后调用 setState 会抛异常

📊 完整生命周期流程

createState() ↓ [created] ↓ initState() ← 只调用一次 ↓ didChangeDependencies() ← InheritedWidget 变化时重调 ↓ [ready] ↓ build() ← setState/依赖变化触发 ↑↓ didUpdateWidget(oldWidget) ← Widget 更新 ↓ deactivate() ← 可能重新插入 ↓ [defunct] ↓ dispose() ← 永久销毁

🏛️ Element 类型体系

Element ├── ComponentElement (组合型) │ ├── StatelessElement │ ├── StatefulElement │ └── InheritedElement │ └── RenderObjectElement (渲染型) ├── SingleChildRenderObjectElement ├── MultiChildRenderObjectElement └── LeafRenderObjectElement

ComponentElement:不直接渲染,组合其他 Widget

RenderObjectElement:对应 RenderObject,参与布局绘制

🏗️ BuildOwner

class BuildOwner { /// 调度构建 void scheduleBuildFor(Element element) { _dirtyElements.add(element); } /// 执行构建 void buildScope(Element context, void Function() callback) { // 1. 执行回调 callback(); // 2. 处理所有 dirty elements while (_dirtyElements.isNotEmpty) { _dirtyElements.sort(); for (element in _dirtyElements) { element.rebuild(); } } } }

职责:管理 Widget 树的构建流程

🔗 WidgetsBinding

mixin WidgetsBinding on BindingBase, ..., RendererBinding { BuildOwner? get buildOwner; Element? get rootElement; /// 添加生命周期观察者 void addObserver(WidgetsBindingObserver observer); /// 处理帧回调 void handleBeginFrame(Duration rawTimeStamp); void handleDrawFrame(); }

职责:Widget 层与 Engine 的桥梁

管理 Element 树、处理系统事件、协调渲染

📝 总结

概念职责
Widget不可变配置描述
ElementWidget 实例,管理生命周期
StateStatefulWidget 的可变状态
BuildOwner调度和管理构建
WidgetsBindingWidget 层与 Engine 桥梁

🦋 理解生命周期是 Flutter 开发的基础

🦋 谢谢!

Flutter Widget 生命周期深度解析
每日技术解读 · 2026-03-03