Flutter框架总览和基础--Window

138 阅读4分钟

Flutter渲染流程总览

image.png Flutter框架存在渲染流水线(Rendering pipline), 由垂直同步信号(Vsync)驱动,Vsync信号由系统提供. 当Flutter接收到Vsync信号后,会按照图示顺序执行一系列动作: 动画(Animate) -> 构建(Build) -> 布局(Layout) -> 绘制(Paint), 最终生成一个场景(Scene)之后送往底层,由GPU绘制到屏幕上.

  • 动画(Animate): 是渲染流水线的第一个阶段, 随着接收到的Vsync信号改变状态(State)
  • 构建(Build): 需要重新构建的Widget在此阶段会重新构建, 也就是调用StatlessWidget.build()或者State.build()的时候
  • 布局(Layout): 调用RenderObject.performLayout(), 确认元素的位置和尺寸
  • 绘制(Paint): 调用RenderObject.paint(), 将渲染对象绘制到上下文(Context)中

以上是整个渲染流水线(Rendering pipline)大致工作流程.

Flutter app 只有在状态发生变化的时候才会触发渲染流水线(Rendering Pipline). 当调用State.setState()时, Flutter经过一系列处理,最终会发起一个调度信号Vsync给底层. 底层在接受Vsync信号后,开始驱动渲染流水线开始运作,最后把新页面显示在屏幕上.

Flutter架构层

Flutter 被设计为一个可扩展的分层系统.它可以被看成是每个独立的组件的系列合集, 上层组件各自依赖下层组件.组件无法越权访问更底层的内容, 并且框架层中的各个部分是可选且替代的.

  • 框架 (Framework) 部分使用Dart语言编写
  • 引擎 (Engine) 部分使用C++进行实现, 引擎为框架提供支撑,也是连接框架和平台 (Android/IOS) 的桥梁.

引擎Engine将底层C++代码包装成Dart代码, 通过dart:ui暴露给Flutter框架层, 该库暴露了最底层的原语, 包括用于驱动输入、图形、和文本渲染的子系统类.

触发流水线的Vsync信号来自引擎(Engine), 渲染完成以后的场景最终会回到引擎显示,并且Vsync信号的调度也是框架(Framework)通过引擎(Engine)来通知系统的. 渲染流程从框架(Framework)和引擎(Engine)交互的角度看,就是下图这样子: image.png

  1. 框架(Framework)通过scheduleFrame通知引擎(Engine)需要调度一帧
  2. 在接收到Vsync信号后,引擎(Engine)首先会回调框架(Framework)的_beginFrame函数,此时渲染流水线(Rending Pipline)进入动画(Animate)阶段.
  3. 在动画(Animate)阶段完成以后. 引擎(Engine)接着会处理微任务队列(Microtask queue)
  4. 微任务(Microtask)执行完, 接着会执行框架(Framework)的_drawFrame函数. 渲染流水线继续按序执行构建(Build)、布局(Layout)和绘制(Paint).
  5. 绘制(Paint)结束以后,框架调用render将绘制完成的场景送入引擎(Engine), 显示在屏幕上.

Window

Flutter中的Window来自库dart:ui, 相关源代码在window.dart中. 在Flutter中, Window是个单例:

/// The [Window] singleton. This object exposes the size of the display, the
/// core scheduler API, the input event callback, the graphics drawing API, and
/// other such core services.
final Window window = new Window._();

Window单例对上层提供屏幕尺寸, 调度接口, 输入事件回调, 图形绘制接口以及其它一些核心服务. 总体来说, Window集中提供了Flutter引擎中和图形界面相关的API. Window中和渲染流水线相关的API如下:

// vsync信号到来以后的回调
FrameCallback _onBeginFrame;
VoidCallback _onDrawFrame;

// 请求引擎engine调度一帧
void scheduleFrame() native 'Window_scheduleFrame';
 
// 绘制完成以后将场景送入引擎engine显示
void render(Scene scene) native 'Window_render';

注意一下函数名称后面的 native 关键字,native表明这个函数是调用到engine层的.和Android中的jni调用类似. 除渲染相关的API, window中还有其他一些重要的API

// 触摸事件的回调
PointerDataPacketCallback _onPointerDataPacket;

// 获取启动时初始页面的路由
String _defaultRouteName() native 'Window_defaultRouteName';

// 发送PlatformMessage. 这个是Platform channels机制的一部分
String _sendPlatformMessage(
  String name, 
  PlatformMessageResponseCallback callback,                       
  ByteData data,
) native 'Window_sendPlatformMessage;

// 收到platform message后的回调
PlatformMessageCallback _onPlatformMessage;

还有一些和local,accessbility相关的API就不列出来了.

总结

Window总体并不算复杂, 基本上是engine层对上层提供的和用户界面相关的接口的封装. Flutter框架是基于Window建立起来的. 有可能的话, 完全可以基于Window搭建起自己的一套框架.