Android技能整理:一文秒懂Flutter跨平台演进及架构
3. Flutter引擎启动既然了解了Flutter的编译产物,那你或许又好奇,Flutter这台引擎如何发动的,怎么跟Native衔接呢?
https://i-blog.csdnimg.cn/blog_migrate/b8715e22eb5908413fc6d17bc7764a70.png
这里以Android为例,熟悉Android的开发者,应该都了解APP启动过程,会执行Application和Activity的onCreate()方法,FlutterApplication和FlutterActivity的onCreate()方法正是毗连Native和Flutter的枢纽。
[*]FlutterApplication.java的onCreate过程重要完成初始化配置、加载引擎libflutter.so、注册JNI方法;
[*]FlutterActivity.java的onCreate过程,通过FlutterJNI的AttachJNI()方法来初始化引擎Engine、Dart捏造机、Isolate、taskRunner等对象。再经过层层处置处罚最终调用main.dart中main()方法,执行runApp(Widget app)来处置处罚整个Dart业务代码。
Flutter引擎启动中会创建有4个TaskRunner以及创建捏造机,分别来看看它们的工作原理。
4. TaskRunner工作原理
Flutter引擎启动过程,会创建UI/GPU/IO这3个线程,会为这些线程依次创建MessageLoop对象,启动后处于epoll_wait等候状态。对于Flutter的消息机制跟Android原生的消息机制有很多相似之处,都有消息(大概使命)、消息队列(或使命队列)以及Looper;有一点差异的是Android有一个Handler类,用于发送消息以及执行回调方法,相对应Flutter中有着相近功能的便是TaskRunner。
https://i-blog.csdnimg.cn/blog_migrate/c19e1ff5357e7be9b57821095bfadcd3.png
上图是从源码中提炼而来的使命处置处罚流程,比官方流程图更容易理解一些复杂流程的时序问题,后续会专门解说个中起因。Flutter的使命队列处置处罚机制跟Android的消息队列处置处罚相通,只不外Flutter分为Task和MicroTask两种范例,引擎和Dart捏造机的事件以及Future都属于Task,Dart层执行scheduleMicrotask()所产生的属于Microtask。
每次Flutter引擎在消费使命时调用FlushTasks()方法,遍历整个延迟使命队列delayed_tasks_,将已到期的使命参加task队列,然后开始处置处罚使命。
[*]Step 1: 查抄task,当task队列不为空,先执行一个task;
[*]Step 2: 查抄microTask,当microTask不为空,则执行microTask;不断循环Step 2 直到microTask队列为空,再回到执行Step 1;
可简单理解为先处置处罚完全部的Microtask,然后再处置处罚Task。由于scheduleMicrotask()方法的调用自身就处于一个Task,执行完当前的task,也就意味着马上执行该Microtask。
了解了其工作机制,再来看看这4个Task Runner的详细工作内容。
[*]Platform Task Runner:运行在Android大概iOS的主线程,只管壅闭该线程并不会影响Flutter渲染管道,平台线程建议不要执行耗时操作;否则可能触发watchdog来竣事该应用。比如Android、iOS都是使用平台线程来传递用户输入事件,一旦平台线程被壅闭则会引起手势事件丢失。
[*]UI Task Runner: 运行在ui线程,比如1.ui,用于引擎执行root isolate中的全部Dart代码,执行渲染与处置处罚Vsync信号,将widget转换天生Layer Tree。除了渲染之外,另有处置处罚Native Plugins消息、Timers、Microtasks等工作;
[*]GPU Task Runner:运行在gpu线程,比如1.gpu,用于将Layer Tree转换为详细GPU指令,执行设备GPU相关的skia调用,转换相应平台的绘制方式,比如OpenGL, vulkan, metal等。每一帧的绘制必要UI Runner和GPU Runner配合完成,任何一个环节延迟都可能导致掉帧;
[*]IO Task Runner:运行在io线程,比如1.io,前3个Task Runner都不允许执行耗时操作,该Runner用于将图片从磁盘读取出来,解压转换为GPU可辨认的格式后,再上传给GPU线程。为了能访问GPU,IO Runner跟GPU Runner的Context在同一个ShareGroup。比如ui.image通过异步调用让IO Runner来异步加载图片,该线程不能执行其他耗时操作,否则可能会影响图片加载的性能。
5. Dart捏造机工作
Flutter引擎启动会创建Dart捏造机以及Root Isolate。DartVM自身也拥有自己的Isolate,完全由捏造机自己管理的,Flutter引擎也无法直接访问。Dart的UI相关操作,是由Root Isolate通过Dart的C++调用,大概是发送消息通知的方式,将UI渲染相关的使命提交到UIRunner执行,这样就可以跟Flutter引擎相关模块举行交互。
何为Isolate,从字面上理解是“隔离”,isolate之间是逻辑隔离的。Isolate中的代码也是按顺序执行,由于Dart没有共享内存的并发,没有竞争的可能性,故不必要加锁,也没有死锁风险。对于Dart程序的并发则必要依靠多个isolate来实现。
https://i-blog.csdnimg.cn/blog_migrate/e2216ce743f8d82ff3d3a8fbb5127c44.png
图解:
[*]isolate堆是运该isolate中代码分配的全部对象的GC管理的内存存储;
[*]vm isolate是一个伪isolate,内里包罗不可变对象,比如null,true,false;
[*]isolate堆能引用vm isolate堆中的对象,但vm isolate不能引用isolate堆;
[*]isolate相互之间不能相互引用;
[*]每个isolate都有一个执行dart代码的Mutator thread,一个处置处罚捏造机内部使命(比如GC, JIT等)的helper thread; 可见,isolate是拥有内存堆和控制线程,捏造机中可以有很多isolate,但相互之间内存不共享,无法直接访问,只能通过dart特有的Port端口通信;isolate除了拥有一个mutator控制线程,另有一些其他辅助线程,比如后台JIT编译线程、GC清理/并发标志线程;
6. Widget架构概览
Flutter引擎启动后执行Dart业务,是通过runApp(Widget app)方法,那Widget又是什么呢?
https://i-blog.csdnimg.cn/blog_migrate/e229fe3412c800e88ab84b33adfb196c.png
Widget是全部Flutter应用程序的基石,Widget可以是一个按钮,一种字体大概颜色,一个结构属性等,在Flutter的UI世界可谓是“万物皆Widget”。常见的Widget子类为StatelessWidget(无状态)和StatefulWidget(有状态);
[*]StatelessWidget:内部没有生存状态,UI界面创建后不会发生改变;
[*]StatefulWidget:内部有生存状态,当状态发生改变,调用setState()方法会触发StatefulWidget的UI发生更新,对于自界说继承自StatefulWidget的子类,必须要重写createState()方法。
三棵树
https://i-blog.csdnimg.cn/blog_migrate/9bbc44785163ffc9b02cb95c02a8dab5.png
图解:
[*]Widget是为Element形貌必要的配置, 负责创建Element,决定Element是否必要更新。Flutter Framework通过差分算法比对Widget树前后的变革,决定Element的State是否改变。当重建Widget树后并未发生改变, 则Element不会触发重绘,则就是Widget树的重建并不一定会触发Element树的重建。
[*]Element体现Widget配置树的特定位置的一个实例,同时持有Widget和RenderObject,负责管理Widget配置和RenderObject渲染。Element状态由Flutter Framework管理, 开发职员只需更改Widget即可。
[*]RenderObject体现渲染树的一个对象,负责真正的渲染工作,比如丈量大小、位置、绘制等都由RenderObject完成。
可见,开发者通过Widget配置,Framework通过比对Widget配置来更新Element,末了调度RenderObject Tree完成结构分列和绘制。
7. 渲染原理
Dart的UI接纳Widget来实现,最终转换为RenderObject,那界面又是如何渲染的呢?
https://i-blog.csdnimg.cn/blog_migrate/beb46a5f1166c2020ec50e51de01e390.png
渲染过程,UI线程完成结构、绘制操作,天生Layer Tree;GPU线程执行合成并光栅化后交给GPU来处置处罚,此中几个关键步调:
[*]Animate: 遍历_transientCallbacks,执行动画回调方法;
[*]Build: 对于dirty的元素会执行build构造,没有dirty元素则不会执行,对应于buildScope()
[*]Layout: 盘算渲染对象的大小和位置,对应于flushLayout(),这个过程可能会嵌套再调用build操作;
[*]Compositing bits: 更新具有脏合成位的任何渲染对象, 对应于flushCompositingBits();
[*]Paint: 将绘制命令记载到Layer, 对应于flushPaint();
[*]Compositing: 将Compositing bits发送给GPU, 对应于compositeFrame();
GPU线程通过skia向GPU硬件绘制一帧的数据,GPU将帧信息生存到FrameBuffer内里,然后视频控制器会根据VSync信号从FrameBuffer取帧数据传递给显示器,从而显示出最终的画面。
8. Platform Channels
Flutter框架提供了UI的控件支持,对于APP除了UI另有其他依靠于Native平台的支持,比如调用Camera的功能,该怎么办呢?为此,Flutter通过提供Platform Channel的功能,使得Dart代码具备与Native交互的本领。
https://i-blog.csdnimg.cn/blog_migrate/e4d7812aefe8fe6c6ac69f8456743e25.png
Platform Channel用于Flutter与Native之间的消息传递,整个过程的消息与相应是异步执行,不会壅闭用户界面。Flutter引擎框架已完成桥接的通道,这样开发者只需在Native层编写定制的Android/iOS代码,即可在Dart代码中直接调用,这也就是Flutter Plugin插件的一种形式。
三、Flutter源码解读
笔者(Gityuan)之前一直从事于Android操作系统底层研发工作,今年刚打仗Flutter,Flutter作为一门全新的跨平台技能框架,不断穷究会发现这是一个小型系统,涉及到的技能很广:
[*]编译技能如何将dart代码转换为AST(抽象语法树),如何汇编转换为呆板码,打包产物是什么?
[*]Flutter这台引擎如何发动的,怎么跟Native原生系统衔接运行,如何辨认产物并加载到内存?
[*]引擎启动后,TaskRunner如何分发使命,跟原生系统消息机制有什么关系?
[*]Dart捏造机如何管理内存,跟isolate又有什么关系?
[*]开发者编写的Widget控件如何渲染到屏幕上?
[*]Flutter如何通过plugin支持移动设备提供的服务?
这些疑问在前面都逐一扼要解答,如果仅仅是用Flutter做业务开发,并不必要把握这么深度技能,不外,知其然知其所以然,能让你游刃有余。
本文同步在我的公号《跨平台技能演进及Flutter未来》,别的为各人创建了Flutter微信交流群,想参加可添加Gityuan微信挚友,备注flutter即可,如发现任何文章有问题欢迎各人直接跟我反馈。
启动篇
[*]深入理解Flutter引擎启动
[*]深入理解Dart捏造机启动
[*]深入理解Flutter应用启动
通信篇
[*]深入理解Flutter消息机制
[*]深入理解Flutter的Platform Channel机制
[*]深入理解Flutter异步Future机制
[*]深入理解Flutter的Isolate创建过程
渲染篇
[*]Flutter渲染机制—UI线程
[*]Flutter渲染机制—GPU线程
[*]深入理解setState更新机制
[*]深入理解Flutter动画原理
后续笔者将连续研究与梳理Flutter内部机制的文章。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到如今。
深知大多数初中级安卓工程师,想要提升技能,往往是自己探索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技能停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给各人,初衷也很简单,就是渴望能够帮助到想自学提升又不知道该从何学起的朋侪,同时减轻各人的负担。
https://i-blog.csdnimg.cn/blog_migrate/6513056d686e5b2610a11575256f6633.png
https://i-blog.csdnimg.cn/blog_migrate/028bc1e618483966819f77ea5b28ad7e.png
https://i-blog.csdnimg.cn/blog_migrate/bbd4862faf6c271cbaaaf03d545ef86d.png
https://i-blog.csdnimg.cn/blog_migrate/390f9a959d0e1dda56ba5b71630656e4.png
由于文件比较大,这里只是将部门目录截图出来,每个节点内里都包罗大厂面经、学习笔记、源码讲义、实战项目、解说视频
如果你以为这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
https://i-blog.csdnimg.cn/blog_migrate/51912d910efb8053933546a0a90e68c2.png
末了
针对Android程序员,我这边给各人整理了一些资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技能;渴望能帮助到各人,也节省各人在网上搜索资料的时间来学习,也可以分享动态给身边挚友一起学习!
[*] Android前沿技能大纲
https://i-blog.csdnimg.cn/blog_migrate/cdcd34cfeaa508309b570fb64df3a022.png
[*] 全套体系化高级架构视频
https://i-blog.csdnimg.cn/blog_migrate/57c8442b5bd6f300c057d2938d1af3f3.png
资料领取:点赞+点击GitHub免费获取
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技能,群内另有技能大牛一起讨论交流解决问题。
+点击GitHub免费获取**
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技能,群内另有技能大牛一起讨论交流解决问题。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]