27

Flutter的一生,最通俗的讲解

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzIxNzU1Nzk3OQ%3D%3D&%3Bmid=2247489679&%3Bidx=1&%3Bsn=95eaf8391742461034f55c10414e715b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

code小生  一个专注大前端领域的技术平台 公众号回复 Android 加入安卓技术群

作者:猩程变

链接:https://juejin.im/post/5d2454a96fb9a07f04206dc7

声明:本文已获  猩程变  授权发表,转发等请联系原作者授权

1

回顾一下Android生命周期

在学习Flutter之前,我们总会要从最基本的东西了解起来,就好比当接触Android的时候,我们学四大组件都要学好久,是否还记得在Android的生命周期?首先让我们回顾下Android中的生命周期。然后再去对比一下Flutter,你就会有更深刻的认识和理解。

F3EjqaF.jpg!web

关于这个就不在多说了,常用场景总结下:

  • 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的引入

在我们的主人公出场前,先认识下它的小伙伴:“ Widget "。

Flutter中几乎所有的对象都是一个  Widget ,与原生开发中“ 控件 ”不同的是,Flutter中的widget的概念更广泛,它不仅可以表示  UI元素 ,也可以表示一些  功能性的组件。 如:用于手势检测的 GestureDetector widget、用于应用主题数据传递的Theme等等。而原生开发中的控件通常只是指UI元素。

3

State的引入

Flutter有两个关键的核心类:“ StatelessWidget ”和 “ StatefulWidget ”。

● StatelessWidget(用于不需要维护状态的场景)

abstract   class   StatelessWidget   extends   Widget

● StatefulWidget(用于需要维护状态的场景)

abstract   class   StatefulWidget   extends   Widget

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

 1@immutable
 2abstract   class   Widget   extends   DiagnosticableTree {
 3  const   Widget({ this.key });
 4  final   Key  key;
 5
 6  @protected
 7  Element   createElement();
 8
 9  @override
10  String   toStringShort() {
11    return   key == null ? '$runtimeType' : '$runtimeType-$key';
12  }
13
14  @override
15  void   debugFillProperties(DiagnosticPropertiesBuilder  properties) {
16    super.debugFillProperties(properties);
17    properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
18  }
19
20  static   bool   canUpdate(Widget   oldWidget, Widget   newWidget) {
21    return   oldWidget.runtimeType == newWidget.runtimeType
22        && oldWidget.key == newWidget.key;
23  }
24}

◀ 左右滑动滚动条查看完整代码块 ▶

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

1@override
2StatefulElement   createElement() => StatefulElement(this);

    ◀ 左右滑动滚动条查看完整代码块 ▶

继续跟踪StatefulElement发现存在一个*widget.createState()*方法,发现了就要继续:

 1class  StatefulElement   extends   ComponentElement {
 2  /// Creates   an   element   that   uses   the   given   widget   as   its   configuration.
 3  StatefulElement(StatefulWidget   widget)
 4      : _state = widget.createState(),
 5        super(widget) {
 6   .....
 7    assert(_state._element == null);
 8    _state._element = this;
 9    assert(_state._widget == null);
10    _state._widget = widget;
11    assert(_state._debugLifecycleState == _StateLifecycle.created);
12  }
13......

◀ 左右滑动滚动条查看完整代码块 ▶

点击  createState  方法我们终于找到了今天的主人公,没错,就是它 ---- State了。

1 @protected
2 State   createState();

4

Flutter生命周期

到了现在这一步,我们已经找到想要的了,正如前面所说,Android有自己的生命周期,那么作为Flutter也有自己独特的生命周期:

NzYBr2j.jpg!web

嗯,我一眼就看到了  initState  这个方法,还记得在网络请求的时候亦或是变量的初始化,总是要写到这个方法里面:

1 @override
2 void   initState() {
3    // TODO: implement   initState
4     super.initState();
5     _loadItemPage();
6 }

我们可以将上述方法分为三个部分进行描述,见下图:

2yayeeq.jpg!web

大致可以看成三个阶段:

● 初始化(插入渲染树)

1、构造函数

不属于生命周期,因为这个时候State的widget属性为空,此时无法在构造函数中访问widget属性。

2、initState

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

3、 didChangeDependencies

这个函数会紧跟在  initState  之后调用。

● 状态改变(在渲染树中存在)

didUpdateWidget

当组件的状态改变的时候就会调用  didUpdateWidget ,比如调用了  setState

● 销毁(从渲染树种移除)

1、deactivate

dispose 之前,会调用这个函数。

2、 dispose

一旦到这个阶段,组件就要被销毁了,这个函数一般会移除监听,清理环境。

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

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

阶段 调用次数 是否支持setState 构造函数 1 否 initState 1 支持但无效(使用setState和不使用一样) didChangeDependencies >=1 支持但无效 didUpdateWidget >=1 支持但无效 deactivate >=1 否 dispose 1 否

5

示例分析

可能有人会说,bb了那么久,show your code please。所以讲了这么多,不来点实际的怎么对的住各位观众呢?来人啊,上代码:

 1import  'package:flutter/material.dart';
 2
 3class   LifeState   extends   StatefulWidget {
 4  @override
 5  _lifeStates  createState() => _lifeStates();
 6}
 7
 8class   _lifeStates   extends   State<LifeState> {
 9  @override
10  void   initState() {
11    // TODO: implement   initState
12    super.initState();
13    print('initState');
14  }
15
16  @override
17  void   didChangeAppLifecycleState(AppLifecycleState   state) {
18    print(state.toString());
19  }
20
21  @override
22  void   didChangeDependencies() {
23    // TODO: implement    didChangeDependencies
24    super.didChangeDependencies();
25    print('didChangeDependencies');
26  }
27
28  @override
29  void   didUpdateWidget(LifeState   oldWidget) {
30    super.didUpdateWidget(oldWidget);
31    print('didUpdateWidget');
32  }
33
34  @override
35  Widget   build(BuildContext   context) {
36    print('build');
37    // TODO: implement   build
38    return  MaterialApp(
39      home: Center(
40          child: GestureDetector(
41        child: new  Text('lifeCycle'),
42        onTap: () {
43          Navigator.of(context)
44              .push(new   MaterialPageRoute(builder: (BuildContext   c) {
45            return   new   Text('sdfs');
46          }));
47        },
48      )),
49    );
50  }
51
52  @override
53  void   reassemble() {
54    // TODO: implement   reassemble
55    super.reassemble();
56    print('reassemble');
57  }
58
59  @override
60  void   deactivate() {
61    // TODO: implement   deactivate
62    super.deactivate();
63    print('deactivate');
64  }
65
66  @override
67  void   dispose() {
68    // TODO: implement   dispose
69    super.dispose();
70    print('dispose');
71  }
72}

  ◀ 左右滑动滚动条查看完整代码块 ▶

测试结果:

● 创建widget

1initState
2didChangeDependencies
3build

● 退出页面

1deactivate
2dispose

● 点击热加载按钮

1reassemble
2didUpdateWidget
3build

●  app从显示到后台(home键)

1AppLifecycleState.inactive
2AppLifecycleState.paused

● app从后台回到前台

1AppLifecycleState.inactive
2AppLifecycleState.resumed

【干货好文】

B3Q7faa.jpg!web

如果你有写博客的习惯

欢迎投稿


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK