Flutter的一生,最通俗的讲解
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.
code小生 一个专注大前端领域的技术平台 公众号回复 Android
加入安卓技术群
作者:猩程变
链接:https://juejin.im/post/5d2454a96fb9a07f04206dc7
声明:本文已获 猩程变 授权发表,转发等请联系原作者授权
1
回顾一下Android生命周期
在学习Flutter之前,我们总会要从最基本的东西了解起来,就好比当接触Android的时候,我们学四大组件都要学好久,是否还记得在Android的生命周期?首先让我们回顾下Android中的生命周期。然后再去对比一下Flutter,你就会有更深刻的认识和理解。
关于这个就不在多说了,常用场景总结下:
-
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也有自己独特的生命周期:
嗯,我一眼就看到了 initState 这个方法,还记得在网络请求的时候亦或是变量的初始化,总是要写到这个方法里面:
1 @override 2 void initState() { 3 // TODO: implement initState 4 super.initState(); 5 _loadItemPage(); 6 }
我们可以将上述方法分为三个部分进行描述,见下图:
大致可以看成三个阶段:
● 初始化(插入渲染树)
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
【干货好文】
如果你有写博客的习惯
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK