Flutter框架分析(一)-- 總覽和Window

Flutter框架分析分析系列文章:前端

《Flutter框架分析(一)-- 總覽和Window》api

《Flutter框架分析(二)-- 初始化》markdown

《Flutter框架分析(三)-- Widget,Element和RenderObject》架構

《Flutter框架分析(四)-- Flutter框架的運行》app

《Flutter框架分析(五)-- 動畫》框架

《Flutter框架分析(六)-- 佈局》less

《Flutter框架分析(七)-- 繪製》函數

前言

在熟悉了Flutter app開發之後,咱們的好奇心會驅使對Flutter框架是如何運行產生諸多疑問,Flutter是如何運轉的?Widget究竟是什麼東西?RenderObject又是個什麼鬼?runApp()以後發生了什麼?調用sateState()以後頁面又是如何刷新的?要解答這些問題,就須要學習一下Flutter框架的源代碼。爲此我會基於源碼寫一系列文章來分析一下Flutter框架。本文是第一篇,主要是先介紹一下Flutter框架的總覽和基礎--Window佈局

總覽

Flutter app的頁面是如何顯示到屏幕上的呢?是什麼驅動Flutter app刷新界面,播放動畫以及響應觸摸事件呢?這一過程能夠用下圖來描述。post

rendering pipline
在Flutter框架中存在着一個渲染流水線(Rendering pipline)。這個渲染流水線是由垂直同步信號(Vsync)驅動的,而Vsync信號是由系統提供的,若是你的Flutter app是運行在Android上的話,那Vsync信號就是咱們熟悉的Android的那個Vsync信號。當Vsync信號到來之後,Flutter 框架會按照圖裏的順序執行一系列動做: 動畫(Animate)、構建(Build)、佈局(Layout)和繪製(Paint),最終生成一個場景(Scene)以後送往底層,由GPU繪製到屏幕上。

  • 動畫(Animate)階段:由於動畫會隨每一個Vsync信號的到來而改變狀態(State),因此動畫階段是流水線的第一個階段。
  • 構建(Build)在這個階段Flutter,在這個階段那些須要被從新構建的Widget會在此時被從新構建。也就是咱們熟悉的StatelessWidget.build()或者State.build()被調用的時候。
  • 佈局(Layout)階段,這時會肯定各個顯示元素的位置,尺寸。此時是RenderObject.performLayout()被調用的時候。
  • 繪製(Paint)階段,此時是RenderObject.paint()被調用的時候。

以上是整個渲染流水線的一個大體的工做過程。

Flutter app只有在狀態發生變化的時候須要觸發渲染流水線。當你的app什麼都不作的時候是不須要從新渲染頁面的。因此,Vsync信號須要Flutter app去調度。好比咱們都知道若是你的某個頁面須要發生變化的時候有可能會調用State.setState(),這個調用Flutter框架最終會發起一個調度Vsync信號的請求給底層。而後底層會在Vsync信號到來的時候驅動渲染流水線開始運做,最後把新的頁面顯示到屏幕上。

Flutter總體架構以下圖所示:

Flutter架構
可見整個Flutter架構是分爲兩部分的。上層的框架(Framework)部分和底層的引擎(Engine)部分。

  • 框架(Framework)部分是用Dart語言寫的,也是本系列文章主要涉及的部分。
  • 引擎(Engine)部分是用C++實現的。引擎爲框架提供支撐,也是鏈接框架和系統(Android/iOS)的橋樑。

觸發渲染流水線的Vsync信號是來自引擎,渲染完成之後的場景也是要送入引擎來顯示,而且Vsync信號的調度也是框架經過引擎來通知系統的。渲染流程從框架和引擎交互的角度用一個示意圖來表示就是下面這個樣子:

渲染調度示意圖

  • 框架通知引擎(scheduleFrame)須要調度一幀。
  • 在系統的Vsync信號到來之後,引擎會首先會回調框架的_beginFrame函數。此時框架的渲染流水線進入動畫(Animate)階段,
  • 在動畫(Animate)階段階段完成之後。引擎會處理完微任務隊列,接着再回調框架的_drawFrame函數。渲染流水線繼續按序運行構建、佈局和繪製。
  • 繪製結束之後,框架調用render將繪製完成的場景送入引擎以顯示到屏幕上。

在前端開發中咱們都會對於用戶界面有一個窗口(Window)的概念,咱們寫的程序的UI都是容納在窗口中的,窗口是框架的根基。界面的繪製,用戶輸入的事件的處理等等都是要經過窗口來管理。Flutter也不例外。上述框架和引擎渲染交互流程也是統一歸入窗口管理的。因此要了解Flutter框架,首先得從Flutter的窗口開始。

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引擎中和圖形界面相關的接口。

Window中和渲染流水線相關的api以下:

// vcync信號到來之後的回調
FrameCallback _onBeginFrame;
VoidCallback _onDrawFrame;
// 請求engine調度一幀
void scheduleFrame() native 'Window_scheduleFrame';
// 繪製完成後將場景送入engine顯示
void render(Scene scene) native 'Window_render';
複製代碼

你們注意一下函數名稱後面的native關鍵字,代表這個函數是調用到engine層的。和Android中的jni調用相似。

除渲染相關的API,window中還有一些其餘重要的API也列一下:

//觸摸事件的回調
PointerDataPacketCallback _onPointerDataPacket;
// 獲取啓動時初始頁面的路由
String _defaultRouteName() native 'Window_defaultRouteName';
// 發送PlatfromMessage。這個是Platform channels機制的一部分
String _sendPlatformMessage(String name,
                              PlatformMessageResponseCallback callback,
                              ByteData data) native 'Window_sendPlatformMessage';
//收到platform message後的回調
PlatformMessageCallback _onPlatformMessage;
複製代碼

還有一些和locale,accessbility的相關的API就不列出來了。

總結

至此,Flutter的Window就大概給你們介紹完了。可見Window其實並不複雜,基本上只是對engine層對上提供的和用戶界面相關的接口的封裝。Flutter框架是基於Window創建起來的。若是你願意的話,徹底能夠基於Window搭建起本身的一套框架來取代Flutter :)。在瞭解了Flutter的渲染流水線和窗口這個基礎設施以後。接下來咱們會以此爲基礎,開始奇妙的Flutter框架之旅,敬請期待。

相關文章
相關標籤/搜索