幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

flutter系列之flutter架构什么的,看完这篇文章就

  简介
  Flutter是google开发的一个跨平台的UI构建工具,flutter目前最新的版本是3。0。5。使用flutter你可以使用一套代码搭建android,IOS,web和desktop等不同平台的应用。做到一次编写到处运行的目的。
  说到一次编写处处运行,大家可能会想到java。那么flutter跟java是不是类似呢?
  对于JAVA来说,在编写完JAVA代码之后,将其编译成为class字节码,然后这个class字节码就可以不需要进行任何转换的在任何平台上运行。其底层原理是JAVA开发了适配不同操作系统和平台的JVM,class实际运行在JVM中,所以对底层到底运行在哪个平台是无感的。一切的适配都是由JVM来执行的。
  Flutter其实更像是C或者C,虽然代码是一样的,但是需要根据不同的平台编译成不同的二进制文件。而Flutter也是一样,虽然我们使用同一套dart代码编写了Flutter程序,但是需要不同的命令编译成不同平台的命令和安装包。
  当然,在开发过程中,flutter提供了虚拟机,实现了hotreload的功能,在代码进行修改之后,可以立刻重载,而不需要重新编译整个代码。
  FLutter这么神奇,那么它到底是怎么工作的呢?Flutter的架构图
  我们先来看下Flutter的架构图,当然这个架构图是官方来的,官方的架构图表示的是权威:
  从上图中,我们可以看到Flutter的架构可以分为三部分,从下到上分别是embedder,Engine和Framework。embedder
  embedder可以称为嵌入器,这是和底层的操作系统进行交互的部分。因为flutter最终要将程序打包到对应的平台中,所以这个嵌入器需要和底层的平台接口进行交互。
  具体而言,对于Android平台使用的是Java和C,对于iOS和macOS平台,使用的是ObjectiveCObjectiveC,对应Windows平台和Linux平台的是C。
  为什么C这么强大?这里就可以看出来了,基本上所有底层的东西都是用C写的。
  回到embedder,为什么叫做嵌入器呢?这是因为Flutter打包的程序,可以作为整个应用程序,也可以作为现有程序的一部分被嵌入使用。engine
  engine也叫做flutterengine,它是flutter中最核心的部分。
  Flutterengine基本上使用C写的。engine的存在是为了支持DartFramework的运行。它提供了Flutter的核心API,包括作图、文件操作、网络IO、dar运行时环境等核心功能。
  engine主要是通过dart:ui暴露给Flutterframework层的。Flutterframework
  这一层是用户编程的接口,我们的应用程序需要和Flutterframework进行交互,最终构建出一个应用程序。
  Flutterframework主要是使用dart语言来编写的。
  framework从下到上,我们有最基础的foundational包,和构建在其上的animation,painting和gestures。
  再上面就是rendering层,rendering为我们提供了动态构建可渲染对象树的方法,通过这些方法,我们可以对布局进行处理。
  接着是widgetslayer,它是rendering层中对象的组合,表示一个小挂件。
  最后是Material和Cupertino库,这些库使用widegts层中提供的小部件,组合成了不同风格的控件集。
  Flutterframework就是这样一层层的构建起来的。
  当然,上面的embedder和engine属于比较底层的东西,我们只需要知道Flutter有这么一个东西,是这么使用的即可。
  真正和我们程序员相关的,就是Flutterframework了。因为我们在编写代码的过程中,需要和Flutterframework打交道。
  接下来,我们重点关注下Flutterframework中的几个核心部分。Widgets
  Widgets翻译成中文就是小插件的意思。Widgets是Flutter中用户界面的基础。你在flutter界面中能够观察到的用户界面,都是Widgets。
  当然这些大的Widgets又是由一个个的小的Widgets组成的,而这些小的Widgets又是由更小的Widgets组成的。
  这样就构成了Widgets的层次依赖结构,这些层次结构的关联关系是通过Widget中的childWidget进行关联的。
  在这种层次结构中,子Widgets可以共享父Widgets的上下文环境。
  Flutter中的Widgets跟其他语言中的类似的Widgets组合有什么不同呢?
  他们最大的不同是,Flutter中的Widgets更多,每个Widgets专注的功能更小。即便是一个很小很小功能,在Flutter中都可以找到与之对应的Widgets。
  这样做的好处就是,你可以使用不同的,非常基础的Widgets任意组合,从而构建出非常复杂的,个性化的大的Widgets。
  当然,它的缺点也非常明显,就是代码里面的Widgets太多了,导致代码中的层级结构特别的多,可能会看的眼花缭乱。
  举个简单的例子,Container是flutter提供的一个基本的容器Widget,我们通常这样来使用它:Container(constraints:BoxConstraints。expand(height:Theme。of(context)。textTheme。headline4!。fontSize!1。1200。0,),padding:constEdgeInsets。all(8。0),color:Colors。blue〔600〕,alignment:Alignment。center,child:Text(HelloWorld,style:Theme。of(context)。textTheme。headline4!。copyWith(color:Colors。white)),transform:Matrix4。rotationZ(0。1),)
  我们向Container中传入了constraints,padding,color,alignment,child,transform等信息。
  我们先来猜一下,这些信息中,哪些是用来构建Widget的?
  大家第一时间想到的应该是child,它本身就是一个Widget,用来表示Container中包含的子对象,这个很好理解。
  但是,除了child这个Widget之外,其他的constraints,padding,color,alignment,transform等都是构成Widget的元素!
  我们来看下Container的build方法:Widgetbuild(BuildContextcontext){Widget?if(childnull(constraintsnull!constraints!。isTight)){currentLimitedBox(maxWidth:0。0,maxHeight:0。0,child:ConstrainedBox(constraints:constBoxConstraints。expand()),);}if(alignment!null)currentAlign(alignment:alignment!,child:current);finalEdgeInsetsGeometry?effectivePaddingpaddingIncludingDif(effectivePadding!null)currentPadding(padding:effectivePadding,child:current);if(color!null)currentColoredBox(color:color!,child:current);if(clipBehavior!Clip。none){assert(decoration!null);currentClipPath(clipper:DecorationClipper(textDirection:Directionality。maybeOf(context),decoration:decoration!,),clipBehavior:clipBehavior,child:current,);}if(decoration!null)currentDecoratedBox(decoration:decoration!,child:current);if(foregroundDecoration!null){currentDecoratedBox(decoration:foregroundDecoration!,position:DecorationPosition。foreground,child:current,);}if(constraints!null)currentConstrainedBox(constraints:constraints!,child:current);if(margin!null)currentPadding(padding:margin!,child:current);if(transform!null)currentTransform(transform:transform!,alignment:transformAlignment,child:current);returncurrent!;}
  从代码中可以看到,Container先是创建了LimitedBox,然后将其嵌入到Align中,再依次嵌入到Padding,ColoredBox,ClipPath,DecoratedBox,ConstrainedBox,Padding和Transform中。这些所有的对象都是Widget。
  这里应该可以理解Flutter中Widget的设计思想了。在Flutter中一切皆可为Widget。Widgets的可扩展性
  和其他的编译成原生语言特性的跨平台实现如Reactnative相比,Flutter对于每个UI都有自己的实现,而不是依赖于操作系统提供的接口。
  这样做的好处就是一切都是由Flutter自己控制的,使用者可以在Flutter的基础上进行无限扩展,而不用受限于系统底层的实现限制。
  另一方面,这样可以减少Flutter在呈现过程中在Flutter代码和平台代码之间来回转换,减少了性能瓶颈,提升效率。
  最后,因为UI的实现和底层的操作系统是分离的,所以Flutter的APP在不同的平台上面可以有统一的外观和实现,可以保证风格的统一。Widgets的状态管理
  Widgets表示的是不可变的用户UI界面结构。虽然结构是不能够变化的,但是Widgets里面的状态是可以动态变化的。
  根据Widgets中是否包含状态,Widgets可以分为stateful和statelesswidget,对应的类是StatefulWidget和StatelessWidget。
  对于有些Widgets来说,比如icon或者Label,它里面本身就不需要状态,这些Widgets就是StatelessWidget。
  但是如果有些Widgets中的某些内容可能需要根据用户或者其他原因来动态变化,则就需要使用StatefulWidget。
  之前提到了Widgets是不可变的,StatefulWidget中的可变数据是存放在对应的State中的,所以StatefulWidgets本身并没有build方法,所有用户界面都是通过State对象来构建的。
  当State发生变化的时候,需要调用setState()方法来通知flutter框架来调用State的build方法,从而将变化反馈到用户界面中。
  既然StatefulWidget是带有状态的,那么这些状态是怎么进行管理和传递的呢?
  State本身提供了一个build方法,用于构建初始的状态:Widgetbuild(BuildContextcontext);
  如果在一个StatefulWidget中需要嵌入另外一个StatefulWidget,那么可以在其对应的State中调用另外一个StatefulWidget的构造函数,将要传递的数据,以构造函数参数的形式传递给子Widget。
  当然这样做是没问题的。但是如果组件的嵌套层数过多的话,这种构造函数的传递方式,显然不能满足我们的需求。
  于是Flutter提供了一个InheritedWidget类,如果我们自定义的类需要共享数据给子Widgets,则可以继承InheritedWidget。
  Inheritedwidgets有两个作用:第一,子Widget可以通过Inheritedwidgets提供的静态of方法拿到离他最近的父Inheritedwidgets实例。
  第二,当Inheritedwidgets改变state之后,会自动触发state消费者的rebuild行为。
  先来看一下inheritedwidgets类的定义:abstractclassInheritedWidgetextendsProxyWidget{constInheritedWidget({Key?key,requiredWidgetchild}):super(key:key,child:child);overrideInheritedElementcreateElement()InheritedElement(this);protectedboolupdateShouldNotify(covariantInheritedWidgetoldWidget);}
  可以看到InheritedWidget是对实际Widget对象的代理,另外还将InheritedWidget封装到了InheritedElement中。
  这里不多讲解InheritedElement,InheritedElement是底层通知机制的实现。
  我们看到InheritedWidget还添加了一个updateShouldNotify,这个方法可以提供给我们控制当前InheritedWidgetrebuilt的时候,是否需要rebuilt继承它的子Widget。
  下面我们看一个InheritedWidget的具体实现:classFrogColorextendsInheritedWidget{constFrogColor({Key?key,requiredthis。color,requiredWidgetchild,}):super(key:key,child:child);finalCstaticFrogColorof(BuildContextcontext){finalFrogColor?resultcontext。dependOnInheritedWidgetOfExactTypeFrogColor();assert(result!null,NoFrogColorfoundincontext);returnresult!;}overrideboolupdateShouldNotify(FrogColorold)color!old。}
  FrogColor中定义了一个Color属性,当Color发生变化的时候,就会调用updateShouldNotify。
  另外,FrogColor还提供了一个of方法,接受的参数是BuildContext,然后调用context。dependOnInheritedWidgetOfExactType去查找离该context最近的FrogColor。
  为什么要使用of方法对context。dependOnInheritedWidgetOfExactType进行封装呢?这是因为,context。dependOnInheritedWidgetOfExactType方法不一定能够找到要找的对象,所以我们需要进行一些异常值的处理。
  另外,有可能of方法返回的对象和context。dependOnInheritedWidgetOfExactType中查找的对象不一样,这都是可以的。
  我们看下of方法的具体使用:classMyPageextendsStatelessWidget{constMyPage({Key?key}):super(key:key);overrideWidgetbuild(BuildContextcontext){returnScaffold(body:FrogColor(color:Colors。green,child:Builder(builder:(BuildContextinnerContext){returnText(HelloFrog,style:TextStyle(color:FrogColor。of(innerContext)。color),);},),),);}}
  还有一个问题,of方法传入的是BuildContext对象,注意,这里的BuildContext必须是InheritedWidget对象本身的后辈,也就是说在对象树中,必须是InheritedWidget的子树。再看下面的例子:classMyOtherPageextendsStatelessWidget{constMyOtherPage({Key?key}):super(key:key);overrideWidgetbuild(BuildContextcontext){returnScaffold(body:FrogColor(color:Colors。green,child:Text(HelloFrog,style:TextStyle(color:FrogColor。of(context)。color),),),);}}
  这个例子中,FrogColor。of方法中的context是FrogColor的父context,所以是找不到FrogColor对象的,这样的使用是错误的。
  当然,除了InheritedWidget,Flutter还提供了很多状态管理的工具,比如provider,bloc,flutterhooks等,也是非常好用的。渲染和布局
  渲染就是将上面我们提到的widgets转换成用户肉眼可以感知的像素的过程。
  Flutter作为一种跨平台的框架,它和普通的跨平台的框架或者原生的框架有什么区别呢?
  首先来考虑一下原生框架。以android为例,首先调用的是andorid框架的java代码,通过调用android系统库提供的进行绘制的组件,最后调用底层的Skia来进行绘制。Skia是一种用CC编写的图形引擎,它调用CPU或GPU在设备上完成绘制。
  那么常见的跨平台框架是怎么运行的呢?它们实际上在原生的代码框架上面又封装了一层。通常使用javascript这样的解释性语言来进行编写,然后编写的代码再和andorid的JAVA或者IOS的ObjectiveC系统库进行交互。这样的结果就是在UI交互或者调用之间会造成显著的性能开销。这也就是通用的跨平台语言不如原生的性能好的原因。
  但是flutter不一样,它并不是用系统自带的UI控件,而是拥有自己的实现。Flutter代码会直接被编译成使用Skia进行渲染的原生代码,从而提升渲染效率。
  接下来,我们具体看一下flutter从代码到渲染的整个流程。首先看一段代码:Container(color:Colors。blue,child:Row(children:〔Image。network(http:www。flydean。com1。png),constText(A),〕,),);
  上面的代码是构建一个Containerwidget。当flutter想要渲染这个widget的时候,会去调用build()方法,然后生成一个widget集合。
  为什么是Widget集合呢?在上面我们也分析过,Container这个widget是由很多个其他的widget组成的,所以,上面的Container会生成下面的widget树:
  上面的就是代码中生成的widget,这些widget在build的过程中,会被转换为elementtree。一个element和一个widget对应。
  element表示的widget的实例。flutter中有两种类型的element,分别是:ComponentElement和RenderObjectElement。
  ComponentElement是其他Element的容器,而RenderObjectElement是真正参与layout和渲染的element。
  因为Widget本身是不可变的,所以任何对于Widget的修改都会返回一个新的Widget。那么是不是所有的变动,都会导致整个elementtree重新渲染呢?
  答案是不会的,flutter仅会重新渲染需要被重新绘制的element。
  接下来,我们看下渲染树是怎么构建的,渲染树中的每个元素叫做RenderObject,它定义了布局和绘制的抽象模型。
  上面我们提到的RenderObjectElement会在渲染的时候转换成为RenderObject,如下所示:
  当然,不同的Renderelement会转换成为不同的Render对象。总结
  Widget和Layout是我们实际在做flutter开发的时候,经常需要使用到的部分,大家需要深入了解和熟练掌握。更多内容请参考http:www。flydean。com01flutterarchitectural
  最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
  欢迎关注我的公众号:程序那些事,懂技术,更懂你!

作为科技大小便护理机器人入选深圳市创新产品推广应用目录近日,深圳市工业和信息化局公布《深圳市创新产品推广应用目录(2022年第三批次)》,深圳作为科技有限公司大小便智能护理机器人成功入选目录名单,成为政府机构优先采购及推荐的产品,……篮网vs开拓者,欧文客场复出,杜兰特欧文火力全开半场合砍34北京时间1月11日11:00篮网vs开拓者,哈登由于左膝伤势休战,但由于客场作战欧文可以登场。开拓者这边虽然刚刚赢了国王,但最近十场比赛输了八场,可以说是惨不忍睹,更糟糕的是:……王者荣耀首届KPI杯来袭,神鸡营大战刘伟家族!花果山也来凑热王者荣耀S25赛季已经接近尾声了,这个赛季大家可能都发现巅峰赛被两个阵营统治了,一个是吕德华带领的神鸡营,经常能看到各种带着神鸡营的ID,另外一个就是刘伟家族,挂着各种各样的刘……永定县,大庸县,大庸市,张家界市一座城市的变迁史张家界市,原名大庸市。是因旅旅游兴起的一座城市。张家界历史悠久。这里古代是古庸国的地盘,建立古庸国的是庸人。庸人自扰这个成语,就来自古代的庸国。明洪武二年(公元13……永恒岛之彩虹回忆装备篇哈喽,大家好,今天小编跟大家分享永恒岛之彩虹回忆里的装备系统,装备系统分为:强化,拼图,重铸,转移,宝石。强化:强化等级不能转移,强化完了之后的装备如果想更换等级的话只能……孩子一日排便五六次是什么原因?如何科学应对儿童急性腹泻?儿童急性腹泻是一种常见的疾病,它可能是由病毒、细菌或者寄生虫引起的,也可能是由于某些药物、食物或者环境因素引起的。当孩子一天排便五六次时,很可能是发生了急性腹泻,家长应该及时采……海阳大秧歌花灯会无人机红包雨龙口南山醉美震撼元宵节来源:【烟台日报大小新闻】2023民俗演艺节海阳大秧歌正月十三空降南山旅游景区南山大佛广场二十余款炫彩灯组、梦幻主题花灯秀、海阳秧歌、超多游乐空降现场……去印度旅游,街边的金黄色大卷饼不要买,得知真相后毫无食欲随着疫情的逐渐放开,越来越多的人开始出去旅游,并且还会选择出国旅游,看看不同于我国的人文环境和风景,尤其是年轻人,越来越多的年轻人喜欢自驾或者跟团去周边国家旅游,因为这样方便并……从最快的冰到大众的冰奥运遗产全民共享央视网消息:北京冬奥会场馆,尤其是新建场馆,是冬奥遗产的重要组成部分。过去一年来,北京冬奥会场馆积极探索向大众开放,努力实现奥运遗产全民共享和可持续利用的新价值。冬奥场馆……不知道怎么选iPhone?看看这篇吧!(附价格)iphone1314两代iPhone之间差距最小的两款,外观没有任何变化,处理器(的GPU)有微小的差距,相机模组提升了不明显的一点点,运存多了2g。如果在这两款之……隆基绿能告别高增长时代盘点一下近期势头最猛的新能源公司,那隆基绿能必须榜上有名。他几乎占全了天时地利人和的优势。先是有外媒放出消息:白宫将宣布两年内不会对太阳能进口征收任何新关税。紧接着,拜登……韶能股份又现股权风波,第三大股东持股将拍卖原宝能系旗下上市公司再现股权风波。广东韶能集团股份有限公司(以下简称韶能股份或公司)2月3日晚间发布关于持股5以上股东所持公司股份将被司法拍卖的提示性公告。公告称,公司第三大股……
逼迫人民币贬值计划落空,美媒中国或已调整计算公式?引言对大众来说,以为不了解经济发展情况之时,总以为人民币升值是好事,但在目前中国的发展情况下来看,人民币贬值才是未来我国应该做的。可中国想要令人民币贬值,但美国而却……护肤小常识生活中大家总是关注怎么让脸更好看,选个什么口红能立马惊艳到对方。在我看来这些是经不住看的,但凡多看几眼,随着每次关注点的转移,总会发现之前忽略的地方。对我来说,不光是在意……实数量子力学检验实验入选2022年国际物理学十大进展北京时间2022年12月20日,美国物理学会(AmericanPhysicalSociety)旗下Physics网站公布今年国际物理学领域的十项重大进展(Highlightso……摩尔定理已死半导体的未来是小芯片和UCIe技术GordonMoore博士是Fairchild的研发总监,当时他撰写了论文将更多组件塞入集成电路,发表在1965年4月19日的《电子学》杂志上。在这篇文章发表之后,加州理工学院……豆瓣9。1闻香识女人我总是知道哪条路是对的,但我从来不走这是属于两个男人的旅程。查理,家境贫寒,靠着兼职和奖学金上学。他正直勇敢,坚守自己的原则,哪怕因为坚守原则,会使他被学校开除。弗兰克中校,曾经是巴顿将军的副官……男篮最新消息26日乔帅线上接受采访,回答提问,曝胡明轩入选乔尔杰维奇被官宣担任中国男篮国家队主教练,已经一个多月过去了,在这段时间他忙着观看CBA的比赛,物色考察队员,未来的集训大名单他已心中有数。据媒体透露,最近中国篮协官方已经通知……难忘的旅行其实说起旅行,对于作为一名公司员工的我来说,机会并不是很多,一年也只有那么固定的几天假期。也许正因为如此,所有的旅行才都给我留下了美好的回忆。要说难忘,还得是十年前妈妈八十岁时……油价调整消息9月6日24时,油价或将大幅上调2022年9月6日24时,国内成品油调价窗口将要再次开启,本周期前8个国内工作日,原油变化率已高达5。76,而国际油价继续震荡上行,因而届时国内成品油价格或将大幅上调,对此车主……群殴格斗赛抽嘴巴大赛!这群人把打架玩出花儿了近10年MMA算是彻底火遍全球,但依旧不乏有人认为此运动是野蛮的代名词。其实大多数MMA比赛看起来就是比较刺激而已,危险性相较拳击、踢拳等格斗运动没什么差异。但有些……真性情!刘畊宏回应梅西输球后哭了有些难过,阿根廷之后会赢的11月23日,知名艺人刘畊宏凌晨发文回应梅西输球后哭了,其发文称:我是有些難過然後跳操流汗到眼睛,剛好有點流鼻水,阿根廷之後的比賽會贏的!至于刘畊宏为何会哭,相信很多网友……iPhone14销量遇冷,苹果最大代工厂富士康希望未来为特斯10月18日消息,据凤凰网科技报道,富士康董事长刘扬伟在公司年度科技日上表示,希望在未来有一天能够为特斯拉公司生产汽车。刘扬伟称,根据富士康过去在个人电脑和手机市场约为4……翻越天山,走进库尔勒西行漫笔(21)离开喀拉峻,沿218国道到达巩乃斯。巩乃斯蒙族语意为绿色的谷地。来此地一看,名不虚传,我们从218国道驶入巩乃斯乡起,便被一种纯粹的绿色深深包裹,泉水萦回,远山含黛,奇峰突兀,……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网