十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
与iOS的ViewController、Android的Activity一样,Flutter中的Widget也存在生命周期,并且通过State来提现。而App则是一个特殊的Widget,除了需要处理视图显示的各个阶段,还需要应对应用从启动到退出所经历的各个状态。
创新互联建站长期为成百上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为柯桥企业提供专业的做网站、成都做网站,柯桥网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制开发。
State的生命周期,指的是在用户参与的情况查下,其关联的Widget所经历的从创建到显示再到更新最后到停止,直至销毁的各个过程阶段。
这些不同的阶段涉及到的特定的任务处理,正确理解State的生命周期至关重要,State的生命周期流程图图,如下所示:
从图中可以看到,State的生命周期可以分为3个阶段:创建、更新、销毁。下面将介绍每一个阶段的具体流程
State初始化时会依次执行:构造方法 - initState - didChangeDependencies - build,随后完成页面渲染
Widget的状态更新,主要由3个方法触发:setState、didChangeDependencies与didUpdateWidget。
一旦这三个方法被调用,Flutter就回销毁旧的Widget,并调用build方法重建Widget
组件销毁相对比较简单,组件被移除,或者页面销毁的时候,系统会调用deactivate和dispose这两个方法来移除或销毁组件
下面这张表格也可以帮助我们理解记忆这些调用实际
视图的生命周期,定义了视图的加载到构建的全过程,其回调机制能够确保我们可以更具视图的状态选择合适的时间做恰当的事情,而App的生命周期,则定义了App从启动到退出的全过程
在原生Android、iOS开发中,有时我们需要再对应的App生命周期事件中做相应的处理,比如App从后台进入前台,从前台退出后台,或者在UI绘制完成后做一些处理。
这样的需求,在原生开发中,可以通过重写Activity、ViewController生命周期回调方法,或者是注册应用程序的相关通知来兼容App的生命周期并做相应的处理。而在Flutter中,我们可以利用WidgetsBindingObserver类,来实现同样的需求。
下面我们看看WidgetsBindingObserver中具体有哪些回调函数:
didChangeAppLifecycleState回调函数中,有一个参数类型为AppLifecycleState的枚举类型,这个枚举类型是Flutter对App生命周期状态的封装,它的常用状态包括:
可以将App切前后台,控制台输出的App状态,可以发现:
我们可以通过下面的这张图直观的了解状态切换过程
除了需要监听App的生命周期回调做相应处理外,根据不同的需求,我们需要再组件宣讲之后做一些与显示安全相关的操作,在iOS中,可以通过GCD的方法,让操作在下一个RunLoop执行,在Android中,可以通过View.post()插入消息队列,来保证在组件渲染后进行相关操作。在Flutter中实现同样的需求会更简单:使用WidgetsBinding来实现即可
WidgetsBinding提供了单词Frame绘制回调和实时Frame绘制回调两种机制来满足不同的需求场景:
看点:Flutter 的争议
InfoQ:我们在看到一些比较比较消极的看法,他们认为 Flutter 正在被悄悄放弃,怎么看待这些声音?
宗心:Gartner 将每个技术成熟度曲线都将技术的生命周期划分为五个关键阶段。技术萌芽期:潜在的技术突破即将开始。早期的概念验证报道和媒体关注引发广泛宣传。通常不存在可用的产品,商业可行性未得到证明。期望膨胀期:早期宣传产生了许多成功案例 — 通常也伴随着多次失败。某些公司会采取行动,但大多数不会。泡沫破裂谷底期:随着实验和实施失败,人们的兴趣逐渐减弱。技术创造者被抛弃或失败。只有幸存的提供商改进产品,使早期采用者满意,投资才会继续。稳步爬升复苏期:有关该技术如何使企业受益的更多实例开始具体化,并获得更广泛的认识。技术提供商推出第二代和第三代产品。更多企业投资试验;保守的公司依然很谨慎。生产成熟期:主流采用开始激增。评估提供商生存能力的标准更加明确。该技术的广泛市场适用性和相关性明显得到回报。基于这个理论,Flutter 应该处于期望膨胀和泡沫破裂之间,一方面看好的人还会继续大力宣传和投入解决问题,同时在尝试落地失败后的公司和个人会极力唱衰,因此我们应该回归本质去看,跨平台技术本身有其特定场景下存在的价值,多平台的研发效能收益是真实的公司需求,目前行业的龙头企业都仍然在持续投入和改进中,谈被放弃为之尚早。
所谓原生级别的流畅,但实际很卡,体验差,而且有些跨端项目一开始用 Flutter,结果性能卡脖子,无奈又回到 Android 和 iOS 分开搞的局面嵌套之美,难以欣赏Flutter 是 KPI 项目,负责人升职完了,华丽转身,留下一地烂摊子……
Flutter跟安卓的Activity、iOS的ViewController一样拥有自己的生命周期, Flutter中一切都是Widget,渲染方式有点像H5的DOM树。
Flutter生命周期可以分为3个阶段:
1、实例化组件并添加到树, 即Navigator.push;
2、状态变化,即打开新的widget或者依赖的上级widget发生变化;
3、从树中移除, 即Navigator.pop。
在Flutter中Widget都是不可变的, 但实际上需要根据对应的状态刷新Widget。 从而产生了StatelessWidget和StatefulWdiget, StatefulWidget是由2个对象Widget和State组成的。
为什么将State和Widget分开呢?
答案是性能, State管理状态(可以理解为Controller),Widget是UI(即View)。 根据状态变化每次生成Widget(即View)可以节省内存,即不必每次创建状态对象State。
构造函数:
同其它高级语言, 只执行一次;
initState:
插入到渲染树时调用,只执行一次。(类似Android Fragment的onCreateView函数)
didChangeDependencies:
1、在初始化initState后执行; 2、显示/关闭其它widget。 3、可执行多次;
didUpdateWidget:
上级节点rebuild widget时, 即上级组件状态发生变化时会触发子widget执行didUpdateWidget;
deative:
有点像Android的onStop函数, 在打开新的Widget或回到这个widget时会执行; 可执行多次;
dispose:
类似于Android的onDestroy, 在执行Navigator.pop后会调用该办法, 表示组件已销毁;
reassemble:
点击闪电会执行,只用于调试时的hot reload。 release版本不会执行该函数。
常见业务场景:
Widget A打开Widget B: Navigator.push(B)
B构造函数---B initState---B didChangeDependencies---B build---A deactive---A didChangeDependencies.
Widget B退出: Navigator.pop
A deactive---A didChangeDependencies---A build---B deactive---B dispose
可以看出, Flutter打开、关闭Widget时跟安卓、iOS的时序一样, 都是先处理即将显示的界面。
activity生命周期和Flutter对应关系:
Flutter提供了WidgetsBindingObserver来监听AppLifecycleState, 而AppLifecycleState有4种状态:
1、 resumed 界面可见, 同安卓的onResume。
2、inactive界面退到后台或弹出对话框情况下, 即失去了焦点但仍可以执行drawframe回调;同安卓的onPause;
3、paused应用挂起,比如退到后台,失去了焦点且不会收到drawframe回调;同安卓的onStop;
4、suspending, iOS中没用,安卓里就是挂起,不会再执行drawframe回调;
下面是生命周期:
1、初次打开widget时,不执行AppLifecycleState的回调;
2、按home键或Power键, AppLifecycleState inactive----AppLifecycleState pause
3、从后台到前台:AppLifecycleState inactive---ApplifecycleState resumed
4、back键退出应用: AppLifecycleState inactive---AppLifecycleState paused
在flutter开发过程中,发现Android手机在App首页点击物理返回按钮时,App会退出并且再次点开App时会重新启动,这代表了上次的退出直接杀死了App,和我们平常的退到手机桌面不同,所以开发了一个单独插件来处理这种情况。
使用步骤如下:
1、pubspec.yaml文件中引入依赖
2、引用插件
3、使用插件来退出App到桌面,并且保持App后台运行
可根据实际情况在_onWillPop方法中处理相关逻辑,比如连续两次点击物理返回按钮才退出到桌面等。
我觉得如果想要实现退出app之后再进入app中来保持登录的状态的话,就必须要不断地保持自己的联网。