Flutter的一辈子

说明: 本篇文章已受权微信公众号 Flutter那些事 独家发布,未经受权,严禁转载!java

1. 前言 在初学新技术以前,咱们总会要从最基本的东西了解起来,就比如当接触Android的时候,咱们学四大组件都要学很久,是否还记得在Android的生命周期?首先让咱们回顾下Android中的生命周期 bash

Android生命周期
关于这个就不在多说了,经常使用场景总结下:

1.启动Activity:系统会先调用onCreate方法,而后调用onStart方法,最后调用onResume,Activity进入运行状态。

2.当前Activity被其余Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。

3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。

4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,而后调用onStop方法,进入停滞状态。

5.用户后退回到此Activity:系统会先调用onRestart方法,而后调用onStart方法,最后调用onResume方法,再次进入运行状态。

6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,然后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。

7.用户退出当前Activity:系统先调用onPause方法,而后调用onStop方法,最后调用onDestory方法,结束当前Activity。
复制代码

emmm,相信小伙伴们如今应该记忆起来了吧,前戏好了,进入主题,聊聊咱们今天的主人公"State"微信

2. Widget概念 在咱们的主人公出场前,先认识下他的小伙伴网络

Flutter中几乎全部的对象都是一个Widget,与原生开发中“控件”不一样的是,
Flutter中的widget的概念更普遍,它不只能够表示UI元素,也能够表示一些功能性的组件如:用于手势检测的 GestureDetector widget、用于应用主题数据传递的Theme等等。
而原生开发中的控件一般只是指UI元素
复制代码

3. State的引入app

  • StatelessWidget(用于不须要维护状态的场景)
abstract class StatelessWidget extends Widget 复制代码
  • StatefulWidget(用于须要维护状态的场景)
abstract class StatefulWidget extends Widget 复制代码

从上述的代码中咱们看到他们都继承了一个东西Widget,那就先简单的看下这个类less

@immutable
abstract class Widget extends DiagnosticableTree {
  const Widget({ this.key });
  final Key key;

  @protected
  Element createElement();

  @override
  String toStringShort() {
    return key == null ? '$runtimeType' : '$runtimeType-$key';
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
  }

  static bool canUpdate(Widget oldWidget, Widget newWidget) {
    return oldWidget.runtimeType == newWidget.runtimeType
        && oldWidget.key == newWidget.key;
  }
}
复制代码

上述代码中有一个咱们很常见的方法,每次在继承的时候都须要重写的一个方法ide

@override
  StatefulElement createElement() => StatefulElement(this);
复制代码

继续跟踪StatefulElement发现存在一个*widget.createState()*方法,发现了就要继续,宁杀错,莫放过函数

class StatefulElement extends ComponentElement {
  /// Creates an element that uses the given widget as its configuration.
  StatefulElement(StatefulWidget widget)
      : _state = widget.createState(),
        super(widget) {
   .....
    assert(_state._element == null);
    _state._element = this;
    assert(_state._widget == null);
    _state._widget = widget;
    assert(_state._debugLifecycleState == _StateLifecycle.created);
  }

复制代码

点击createState方法咱们终于找到了今天的主人公,没错,就是它,State,跑不掉了。测试

@protected
  State createState();
复制代码
  1. 生命周期 到了如今这一步,咱们已经找到想要的了,正如前面所说,Android有本身的生命周期,那么做为Flutter也有本身独特的生命周期
    Flutter生命周期
    嗯,我一眼就看到了initState这个方法,还记得在网络请求的时候亦或是变量的初始化,老是要写到这个方法里面
@override
 void initState() {
   // TODO: implement initState
   super.initState();
   _loadItemPage();
 }
复制代码

咱们能够将上述方法分为三个部分进行描述,见下图: ui

在这里插入图片描述
大体能够当作三个阶段

  • 初始化(插入渲染树)
  • 构造函数
不属于生命周期,由于这个时候State的widget属性为空,此时没法在构造函数中访问widget属性
复制代码
  • initState
/// Called when this object is inserted into the tree.
  
这个函数在生命周期中只调用一次。这里能够作一些初始化工做,好比初始化State的变量
复制代码
  • didChangeDependencies
/// Called when a dependency of this [State] object changes.
 
这个函数会紧跟在initState以后调用
复制代码
  • 状态改变(在渲染树中存在)
  • didUpdateWidget
/// Called whenever the widget configuration changes.
 
当组件的状态改变的时候就会调用didUpdateWidget,好比调用了setStat
复制代码
  • 销毁(从渲染树种移除)
  • deactivate
/// Called when this object is removed from the tree.
 
在dispose以前,会调用这个函数。
复制代码
  • dispose
/// Called when this object is removed from the tree permanently.
 
一旦到这个阶段,组件就要被销毁了,这个函数通常会移除监听,清理环境。
复制代码

这个函数在生命周期中只调用一次。这里能够作一些初始化工做,好比初始化State的变量。

大致这样吧,最后来个图表总结下

阶段 调用次数 是否支持setState
构造函数 1
initState 1 支持但无效(使用setState和不使用同样)
didChangeDependencies >=1 支持但无效
didUpdateWidget >=1 支持但无效
deactivate >=1
dispose 1
  1. 示例分析 可能有人会说,bb了那么久,毛都没看到一根,因此讲了这么多,不来点实际的怎么对的住以前的bb呢?来人啊,上代码
import 'package:flutter/material.dart';

class LifeState extends StatefulWidget {
  @override
  _lifeStates createState() => _lifeStates();
}

class _lifeStates extends State<LifeState> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print('initState');
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print(state.toString());
  }

  @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
    print('didChangeDependencies');
  }

  @override
  void didUpdateWidget(LifeState oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('didUpdateWidget');
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    // TODO: implement build
    return MaterialApp(
      home: Center(
          child: GestureDetector(
        child: new Text('lifeCycle'),
        onTap: () {
          Navigator.of(context)
              .push(new MaterialPageRoute(builder: (BuildContext c) {
            return new Text('sdfs');
          }));
        },
      )),
    );
  }

  @override
  void reassemble() {
    // TODO: implement reassemble
    super.reassemble();
    print('reassemble');
  }

  @override
  void deactivate() {
    // TODO: implement deactivate
    super.deactivate();
    print('deactivate');
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    print('dispose');
  }
}

复制代码

测试结果

  1. 建立widget
initState
didChangeDependencies
build
复制代码
  1. 退出页面
deactivate
dispose
复制代码
  1. 点击热加载按钮
reassemble
didUpdateWidget
build
复制代码
  1. app从显示到后台(home键)
AppLifecycleState.inactive
AppLifecycleState.paused
复制代码
  1. app从后台回到前台
AppLifecycleState.inactive
AppLifecycleState.resumed
复制代码
相关文章
相关标签/搜索