美文网首页Android开发Android开发经验谈Android技术知识
面试官问我:Widget 和 element 和 RenderO

面试官问我:Widget 和 element 和 RenderO

作者: jett老师 | 来源:发表于2020-05-28 21:56 被阅读0次

    面试的开始

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

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

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

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

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

    • initState()

    界面初始化状态时调用

    • didChangeDependencies()

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

    • build()

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

    在调用initState()之后。

    在调用didUpdateWidget()之后。

    在调用setState()之后。

    在调用didChangeDependencies()之后。

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

    • reassemble()

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

    • didUpdateWidget()

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

    • deactivate()

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

    • dispose()

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

    应该没有漏,不愧是我

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

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

    • Widget实际上就是Element的配置数据,Widget树实际上是一个配置树,而真正的UI渲染树是由Element构成;不过,由于Element是通过Widget生成,所以它们之间有对应关系,所以在大多数场景,我们可以宽泛地认为Widget树就是指UI控件树或UI渲染树。

    • 一个Widget对象可以对应多个Element对象。这很好理解,根据同一份配置(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是用户界面的一部分,并且是不可变的。* Element是在树中特定位置Widget的实例。* 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 混和开发

    相关文章

      网友评论

        本文标题:面试官问我:Widget 和 element 和 RenderO

        本文链接:https://www.haomeiwen.com/subject/ipmzahtx.html