前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 生命周期详解

Flutter 生命周期详解

作者头像
子晋
发布2022-01-19 13:59:03
1.1K0
发布2022-01-19 13:59:03
举报
文章被收录于专栏:子晋城子晋城子晋城

简介

Flutter 跟 Android 的 Activity、iOS 的 ViewController 一样都拥有自己的生命周期。在 Flutter 中几乎所有的对象都是一个 Widget,其中 Widget 又分为 StatelessWidget(即:无状态的 Widget) 和 StatefulWidget (即:有状态的 Widget),这里所说的 Flutter 的生命周期其实就是讲 StatefulWidget 的生命周期,它存在于 framework.dart 的 State 类中。

代码实测

写个有状态类并混入 WidgetsBindingObserver 配合监听特殊状态及其一个按钮,调用 setState, 给生命周期的方法新增打印:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: '生命周期',
      home: new LiftCycle(),
    );
  }
}

class LiftCycle extends StatefulWidget {
  @override
  _LiftCycleState createState() => _LiftCycleState();
}

class _LiftCycleState extends State<LiftCycle> with WidgetsBindingObserver {
  int count = 0;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    print('初始化 initState');
  }

  @override
  void didUpdateWidget(LiftCycle oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('组件更新 didUpdateWidget');
  }

  @override
  void reassemble() {
    super.reassemble();
    print('重新安装 reassemble');
  }

  @override
  void deactivate() {
    super.deactivate();
    print('停用  deactivate');
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
    print('销毁 dispose');
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print('特殊状态 state:$state');
  }

  @override
  void setState(fn) {
    super.setState(fn);
    print('状态刷新 setState');
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text('生命周期')),
      body: new Center(
        child: new FlatButton(
          onPressed: () => setState(() => count++),
          child: new Text('$count'),
        ),
      ),
    );
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('依赖改变 didChangeDependencies');
  }
}

然后我们现在来看看打印流程,正常打开 App 什么都不操作,就打印了:

I/flutter (15867): 初始化 initState
I/flutter (15867): 依赖改变 didChangeDependencies
I/flutter (15867): 重新安装 reassemble
I/flutter (15867): 组件更新 didUpdateWidget

热重载打印:

I/flutter (16141): 重新安装 reassemble
I/flutter (16141): 组件更新 didUpdateWidget
Reloaded 0 of 468 libraries in 186ms.

点击按钮打印:

I/flutter (16141): 状态刷新 setState
// count也+1了,说明重新调用过build。

流程图

构造函数:

构造函数不属于生命周期,必然是要第一个调用的,也就是调用前 State 的 widget 属性为空。

initState 初始化:

当此对象插入树中时调用,框架会调用一次此方法并不会再次重复执行, 如果 State 的 build 方法依赖于本身可以更改状态的对象,例如:ChangeNotifier 或 Stream, 或者某些其他可以订阅的对象接收通知,可以在此方法订阅,但记得去 dispose 取消订阅。

didChangeDependencies 依赖改变:

顾名思义,依赖项更改时调用,但也会在 initState 之后调用, 在这个方法调用 BuildContext.inheritFromWidgetOfExactType 是安全的。

build 构建:

会在以下场景调用:

  • initState() 之后。
  • didUpdateWidget() 之后。
  • setState() 之后。
  • didChangeDependencies() 之后。
  • State 对象从树中一个位置移除后会调用 deactivate,然后又重新插入到树的其它位置之后。

reassemble 重新安装:

专门为了开发调试而提供的,在热重载 hot reload 时会被调用,此回调在 Release 模式下永远不会被调用。

didUpdateWidget 组件更新:

当组件的状态改变的时候就会调用 didUpdateWidget(),比如调用了 setState(), 在 widget 重新构建时,Flutter framework 会调用 Widget.canUpdate 来检测 Widget 树中同一位置的新旧节点, 然后决定是否需要更新,如果 Widget.canUpdate 返回 true 则会调用此回调。正如之前所述,Widget.canUpdate 会在 新旧 widget 的 key 和 runtimeType 同时相等时会返回 true,也就是说在新旧 widget 的 key 和 runtimeType 同时相等时 didUpdateWidget() 就会被调用。

deactivate 暂停:

State 对象从树中被移除时(在 dispose 之前),会调用这个函数来将对象暂停。

dispose 销毁:

当 State 对象被销毁时调用,通常在此回调中释放资源和移除监听。

特殊状态

我们自定义的 State 类混入了 WidgetsBindingObserver,所以可以使用他的暂停和恢复。

初始化:

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addObserver(this); // 在这初始化了
  print('初始化 initState');
}

销毁:

@override
void dispose() {
  super.dispose();
  WidgetsBinding.instance.removeObserver(this); // 在这销毁
  print('销毁 dispose');
}

使用:

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  print('特殊状态 state:$state');
}

这个 didChangeAppLifecycleState 是 WidgetsBindingObserver 类的一个方法,可以用来判断当前的状态是在前台还是后台。

这个方法接收一个AppLifecycleState类型的枚举:

枚举值

含义

resumed

程序可见,并响应用户输入。

inactive

处于非活动状态,未收到用户输入。

paused

程序当前不可见,不响应用户输入,并且在后台运行。

suspending

程序将暂时暂停。

AppLifecycleState 实测

当App返回到桌面或者其他不可见状态,但并未结束:

I/flutter ( 2428): 特殊状态 state:AppLifecycleState.inactive
I/flutter ( 2428): 特殊状态 state:AppLifecycleState.paused

当App回到可见状态:

I/flutter ( 2428): 特殊状态 state:AppLifecycleState.inactive
I/flutter ( 2428): 特殊状态 state:AppLifecycleState.resumed

流程图:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 代码实测
  • 流程图
  • 特殊状态
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档