Android开发Android开发经验谈Android技术知识

面试官问我:Widget 和 element 和 RenderO

2020-05-28  本文已影响0人  jett老师

面试的开始

一群人紧张兮兮的坐在面试等待区,一眼望去全是格子衫,戴眼镜身后背着一个大书包,个个发量“惊人”我想这一定都是高级架构师,人才啊。但是我根本没在怕,面试前1000道面试题,可没白刷和这么多书可没白看。

面试官:我之前问你的关于Flutter的知识,你不仅都能回答下来,而且关于里面很细的知识点你也知道,你是不是有看谁的文章,还是有什么其他学习的途径。

我其实是有个小习惯,我喜欢搜集面试题和资料,然后自己看,自己刷。(心里话)我就是比别人多学了点知识而已,嗯!

面试官:说一下State生命周期

我:我还是正经一点回答好了。嗯,是这样的一个StatefulWidget类会对应一个State类,State表示与其对应的StatefulWidget要维护的状态,

界面初始化状态时调用

当state状态对象发生变化时调用(典型的场景是当系统语言Locale或应用主题改变时,Flutter framework会通知widget调用此回调。)

主要是用于构建Widget子树,调用时机如下:

在调用initState()之后。

在调用didUpdateWidget()之后。

在调用setState()之后。

在调用didChangeDependencies()之后。

在State对象从树中一个位置移除后(会调用deactivate)又重新插入到树的其它位置之后。

主要用于调试,热重载时调用,release环境下不会调用

用于更新widget ,Widget.canUpdate返回true则会调用此回调

从widget树中移除State对象t时调用(位置交换)

从widget树中移除State对象,并不再插入此State对象时调用(一般用于释放资源)

应该没有漏,不愧是我

面试官:那你再说一下Widget与Element

我:这个刚好刷到过(暗喜)

面试官:Dart单线程模型你来说一下这块

我:额!!!(我上面回答的不好吗?感觉要凉了啊!怎么面试官冷这个脸)是这样的,我想一下怎么说比较好。

答:在Java和OC中,如果程序发生异常且没有被捕获,那么程序将会终止,但在Dart或JavaScript中则不会,究其原因,这和它们的运行机制有关系,Java和OC都是多线程模型的编程语言,任意一个线程触发异常且没被捕获时,整个进程就退出了。但Dart和JavaScript不同,它们都是单线程模型,运行机制很相似(但有区别)。

大概就下面这个图

Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。从图中可以发现,微任务队列的执行优先级高于事件队列。

现在我们来介绍一下Dart线程运行过程,如上图中所示,入口函数 main() 执行完后,消息循环机制便启动了。首先会按照先进先出的顺序逐个执行微任务队列中的任务,当所有微任务队列执行完后便开始执行事件队列中的任务,事件任务执行完毕后再去执行微任务,如此循环往复,生生不息。

在Dart中,所有的外部事件任务都在事件队列中,如IO、计时器、点击、以及绘制事件等,而微任务通常来源于Dart内部,并且微任务非常少,之所以如此,是因为微任务队列优先级高,如果微任务太多,执行时间总和就越久,事件队列任务的延迟也就越久,对于GUI应用来说最直观的表现就是比较卡,所以必须得保证微任务队列不会太长。值得注意的是,我们可以通过Future.microtask(…)方法向微任务队列插入一个任务。

在事件循环中,当某个任务发生异常并没有被捕获时,程序并不会退出,而直接导致的结果是当前任务的后续代码就不会被执行了,也就是说一个任务中的异常是不会影响其它任务执行的。

面试官:Widget 和 element 和 RenderObject 之间的关系?

我:

Widget会被inflate(填充)到Element,并由Element管理底层渲染树。Widget并不会直接管理状态及渲染,而是通过State这个对象来管理状态。Flutter创建Element的可见树,相对于Widget来说,是可变的,通常界面开发中,我们不用直接操作Element,而是由框架层实现内部逻辑。就如一个UI视图树中,可能包含有多个TextWidget(Widget被使用多次),但是放在内部视图树的视角,这些TextWidget都是填充到一个个独立的Element中。Element会持有renderObject和widget的实例。记住,Widget 只是一个配置,RenderObject 负责管理布局、绘制等操作。

在第一次创建 Widget 的时候,会对应创建一个 Element, 然后将该元素插入树中。如果之后 Widget 发生了变化,则将其与旧的 Widget 进行比较,并且相应地更新 Element。重要的是,Element 不会被重建,只是更新而已。

大概还有下面这些问题:

Flutter中的Widget、State、Context 的核心概念?是为了解决什么问题?

Widget: 在Flutter中,几乎所有东西都是Widget。将一个Widget想象为一个可视化的组件(或与应用可视化方面交互的组件),当你需要构建与布局直接或间接相关的任何内容时,你正在使用Widget。

Widget树: Widget以树结构进行组织。包含其他Widget的widget被称为父Widget(或widget容器)。包含在父widget中的widget被称为子Widget。

Context: 仅仅是已创建的所有Widget树结构中的某个Widget的位置引用。简而言之,将context作为widget树的一部分,其中context所对应的widget被添加到此树中。一个context只从属于一个widget,它和widget一样是链接在一起的,并且会形成一个context树。

State: 定义了StatefulWidget实例的行为,它包含了用于”交互/干预“Widget信息的行为和布局。应用于State的任何更改都会强制重建Widget。

这些状态的引入,主要是为了解决多个部件之间的交互和部件自身状态的维护。

Widget的两种类型是什么?

StatelessWidget: 一旦创建就不关心任何变化,在下次构建之前都不会改变。它们除了依赖于自身的配置信息(在父节点构建时提供)外不再依赖于任何其他信息。比如典型的Text、Row、Column、Container等,都是StatelessWidget。它的生命周期相当简单:初始化、通过build()渲染。

StatefulWidget: 在生命周期内,该类Widget所持有的数据可能会发生变化,这样的数据被称为State,这些拥有动态内部数据的Widget被称为StatefulWidget。比如复选框、Button等。State会与Context相关联,并且此关联是永久性的,State对象将永远不会改变其Context,即使可以在树结构周围移动,也仍将与该context相关联。当state与context关联时,state被视为已挂载。StatefulWidget由两部分组成,在初始化时必须要在createState()时初始化一个与之相关的State对象。

面试结束

嗯,小伙子不错不错,分析得很到位,flutter这块很熟悉嘛!最后问你一个问题。

面试官:State 对象的初始化流程?

我:这个不会,我资料里面还没有,这个是个好问题,我回去查查放进我收录的资料里面。有机会下次我来告诉你(心里话)这次凉了!

总结

记住,没有最好的技术,只有最适合的技术,不要为了用而用

关于flutter基础知识我就先介绍这么多,flutter在面试里面基本上也是跟我前面写的一样必问的。

面试的思路还是一样,要知其然,也要知其所以然,就是要知道为啥用,用了有啥好处,有啥坑。

面试官不喜欢只知道用的,你只会用那哪天线上出问题怎么办?你难道在旁边拜佛?

Tip:本来有很多我准备的资料的,还有上面的面试题都不完整,但是由于都是外链,不合适的分享。所以需要的朋友私信我【学习】我免费分享给你。

或者直接点击下面链接即可领取我都搜集好了

Android学习PDF+架构视频+面试文档+源码笔记

Flutter系统学习路线

Flutter学习电子书

Flutter大厂精选面试题

Flutter 混和开发

上一篇下一篇

猜你喜欢

热点阅读