<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                Flutter app的入口函數就是`runApp()`。 ~~~ void main() { runApp(MyApp()); } ~~~ `runApp()`的函數體位于`widgets/binding.dart`。 ~~~ void runApp(Widget app) { WidgetsFlutterBinding.ensureInitialized() ..attachRootWidget(app) ..scheduleWarmUpFrame(); } ~~~ ensureInitialized:確保各種Binding的初始化 attachRootWidget :為渲染樹加入根節點 scheduleWarmUpFrame:渲染第一幀 ## ensureInitialized WidgetsFlutterBinding 實際上就是把Widget和Flutter綁定在一起的意思。 ~~~ class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding { static WidgetsBinding ensureInitialized() { if (WidgetsBinding.instance == null) WidgetsFlutterBinding(); return WidgetsBinding.instance; } } ~~~ 這個類繼承自`BindingBase`并且混入(`Mixin`)了很多其他類,看名稱都是不同功能的綁定。而靜態函數`ensureInitialized()`所做的就是返回一個`WidgetsBinding.instance`單例。 混入的那些各種綁定類也都是繼承自抽象類`BindingBase`的。 ~~~ abstract class BindingBase { BindingBase() { ... initInstances(); ... } ... ui.Window get window => ui.window; } ~~~ 關于抽象類`BindingBase`,你需要了解兩個地方,一個是在其構造的時候會調用函數`initInstances()`。這個函數會由其子類,也就是上面說那些各種混入(Mixin)的綁定類各自實現,具體的初始化都是在其內部實現的。另一個就是`BindingBase`有一個`getter`,返回的是`window`。 我們需要重點關注的是`SchedulerBinding`,`RendererBinding`和`WidgetsBinding`。這3個是渲染流水線的重要存在。 ### GestureBinding 手勢綁定。 ~~~ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, HitTestTarget { @override void initInstances() { super.initInstances(); _instance = this; window.onPointerDataPacket = _handlePointerDataPacket; } ~~~ 主要的事情就是給`window`設置了一個手勢處理的回調函數。 ### ServicesBinding 服務綁定 ~~~ mixin ServicesBinding on BindingBase { @override void initInstances() { super.initInstances(); _instance = this; window ..onPlatformMessage = BinaryMessages.handlePlatformMessage; initLicenses(); } ~~~ 這個綁定主要是給`window`設置了處理Platform Message的回調。 ### SchedulerBindind 調度綁定 ~~~ mixin SchedulerBinding on BindingBase, ServicesBinding { @override void initInstances() { super.initInstances(); _instance = this; window.onBeginFrame = _handleBeginFrame; window.onDrawFrame = _handleDrawFrame; SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage); } ~~~ 這個綁定主要是給`window`設置了`onBeginFrame`和`onDrawFrame`的回調,回憶一下上一篇文章講渲染流水線的時候,當Vsync信號到來的時候engine會回調Flutter的來啟動渲染流程,這兩個回調就是在`SchedulerBinding`管理的。 ### PaintingBinding 繪制綁定 ~~~ mixin PaintingBinding on BindingBase, ServicesBinding { @override void initInstances() { super.initInstances(); _instance = this; _imageCache = createImageCache(); } ~~~ 這個綁定只是創建了個圖片緩存 ### SemanticsBinding 輔助功能綁定 ~~~ mixin SemanticsBinding on BindingBase { @override void initInstances() { super.initInstances(); _instance = this; _accessibilityFeatures = window.accessibilityFeatures; } ~~~ 這個綁定管理輔助功能 ### RendererBinding 渲染綁定 ~~~ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureBinding, SemanticsBinding, HitTestable { @override void initInstances() { super.initInstances(); _instance = this; _pipelineOwner = PipelineOwner( onNeedVisualUpdate: ensureVisualUpdate, onSemanticsOwnerCreated: _handleSemanticsOwnerCreated, onSemanticsOwnerDisposed: _handleSemanticsOwnerDisposed, ); window ..onMetricsChanged = handleMetricsChanged ..onTextScaleFactorChanged = handleTextScaleFactorChanged ..onPlatformBrightnessChanged = handlePlatformBrightnessChanged ..onSemanticsEnabledChanged = _handleSemanticsEnabledChanged ..onSemanticsAction = _handleSemanticsAction; initRenderView(); _handleSemanticsEnabledChanged(); assert(renderView != null); addPersistentFrameCallback(_handlePersistentFrameCallback); _mouseTracker = _createMouseTracker(); } ~~~ #### 第一步:實例化PipelineOwner 實例化了一個`PipelineOwner`類。這個類負責管理驅動我們之前說的渲染流水線。 #### 第二步:設置window回調函數 給`window`設置了一系列回調函數,處理屏幕尺寸變化,亮度變化等。 #### 第三步:實例化了一個RenderView類 ~~~ void initRenderView() { assert(renderView == null); renderView = RenderView(configuration: createViewConfiguration(), window: window); renderView.scheduleInitialFrame(); } ~~~ 這個函數實例化了一個`RenderView`類。`RenderView`繼承自`RenderObject`。我們都知道Flutter框架中存在這一個渲染樹(render tree)。。這個`RenderView`就是渲染樹(render tree)的根節點。 #### 第四步:addPersistentFrameCallback 調用`addPersistentFrameCallback`添加了一個回調函數。渲染流水線的主要階段都會在這個回調里啟動。 ### WidgetsBinding 組件綁定 ~~~ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererBinding, SemanticsBinding { @override void initInstances() { super.initInstances(); _instance = this; buildOwner.onBuildScheduled = _handleBuildScheduled; window.onLocaleChanged = handleLocaleChanged; window.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged; SystemChannels.navigation.setMethodCallHandler(_handleNavigationInvocation); SystemChannels.system.setMessageHandler(_handleSystemMessage); } ~~~ 這個綁定的初始化先給`buildOwner`設置了個`onBuildScheduled`回調,還記得渲染綁定里初始化的時候實例化了一個`PipelineOwner`嗎?這個`BuildOwner`是在組件綁定里實例化的。它主要負責管理Widget的重建,記住這兩個"owner"。他們將會Flutter框架里的核心類。接著給`window`設置了兩個回調,因為和渲染關系不大,就不細說了。最后設置`SystemChannels.navigation`和`SystemChannels.system`的消息處理函數。這兩個回調一個是專門處理路由的,另一個是處理一些系統事件,比如剪貼板,震動反饋,系統音效等等。 ## attachRootWidget ~~~ void attachRootWidget(Widget rootWidget) { _renderViewElement = RenderObjectToWidgetAdapter<RenderBox>( container: renderView, debugShortDescription: '[root]', child: rootWidget ).attachToRenderTree(buildOwner, renderViewElement); } ~~~ ~~~ class RenderObjectToWidgetAdapter<T extends RenderObject> extends RenderObjectWidget { /// Creates a bridge from a [RenderObject] to an [Element] tree. /// /// Used by [WidgetsBinding] to attach the root widget to the [RenderView]. RenderObjectToWidgetAdapter({ this.child, this.container, this.debugShortDescription }) : super(key: GlobalObjectKey(container)); @override RenderObjectToWidgetElement<T> createElement() => RenderObjectToWidgetElement<T>(this); @override RenderObjectWithChildMixin<T> createRenderObject(BuildContext context) => container; ... } ~~~ 1. 實例化 `RenderObjectToWidgetAdapter`,將它widget tree的根節點 2. createElement()返回的就是`RenderObjectToWidgetElement`,就是element tree的根節點了 3. `RendererBinding`的初始化的時候,我們得到了一個`RenderView`的實例 ,createRenderObject()返回的就是這個實例,就是render tree的根節點 `attachToRenderTree`做的事情屬于我們之前說的渲染流水線的構建(Build)階段,這時會根據我們自己的widget生成element tree和render tree。構建(Build)階段完成以后,那自然是要進入布局(Layout)階段和繪制(Paint)階段了。 ## scheduleWarmUpFrame ~~~ void scheduleWarmUpFrame() { ... Timer.run(() { ... handleBeginFrame(null); ... }); Timer.run(() { ... handleDrawFrame(); ... }); } ~~~ 這個函數其實就調了兩個函數,就是之前我們講`window`的時候說的兩個回調函數`onBeginFrame`和`onDrawFrame`,這里其實就是在具體執行這兩個回調。最后渲染出來首幀場景送入engine顯示到屏幕。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看