zoukankan      html  css  js  c++  java
  • Flutter boost实现原理简介

    # Flutter_boost
     
    A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL). 
    ## FlutterBoost widget tree in flutter end
    The many functions an apis, let's just run the example_new and have look at it, below is the widget tree, when push flutter with container it will increase a new `BoostContainerWidget`, otherwise the pages will be add to the same `BoostContainerWidget`

     

    There are so many api in the source code, let's just foucs on the push a route in flutter from end to end, in this way it can easy to known the author's intends.

    ## Below is the call stack to push a fluter page via native
    ```dart
    //Add the `ContainerOverlayEntry` to the `List<OverlayEntry>`, provider for the `_Theatre` to present
    //Tips: if the below entry will be hidden from the `_Theatre` if it set to `opaque`
    OverlayState.insert (flutter/packages/flutter/lib/src/widgets/overlay.dart:347)
    //create ContainerOverlayEntry, it can generated a `BoostContainerWidget` to hold on the pages for current container
    ContainerOverlay.refreshSpecificOverlayEntries (project/flutter_boost/lib/src/container_overlay.dart:88)
    FlutterBoostAppState.refreshOnPush (project/flutter_boost/lib/src/flutter_boost_app.dart:603)
    //Save current stackInfo for restart
    FlutterBoostAppState.pushContainer (project/flutter_boost/lib/src/flutter_boost_app.dart:287)
    //corresponding BoostContainer or findExsitContainer
    BoostFlutterRouterApi.pushRoute.<anonymous closure> (project/flutter_boost/lib/src/boost_flutter_router_api.dart:24)
    //push new flutter route with the pageName and container uniqueId from native
    BoostFlutterRouterApi._addInOperationQueueOrExcute (project/flutter_boost/lib/src/boost_flutter_router_api.dart:96)
    //check the overlayState exsit or not
    ...
    FlutterRouterApi.setup.<anonymous closure> (project/flutter_boost/lib/src/messages.dart:78)
    //Routes events binding
    BasicMessageChannel.setMessageHandler.<anonymous closure> (flutter/packages/flutter/lib/src/services/platform_channel.dart:73)
    //message binding
    _DefaultBinaryMessenger.handlePlatformMessage (flutter/packages/flutter/lib/src/services/binding.
    ...
    PlatformDispatcher._dispatchPlatformMessage (dart:ui/platform_dispatcher.dart:520)
    _dispatchPlatformMessage (dart:ui/hooks.dart:90)
    .... engine ...
    Native push new flutter page when container will appear
    Native create container
    ```
    ## Push a flutter page via flutter
    The flutter_boost use `BoostNavigator` to manager the navigation in flutter end, when tap a button will trigger this method below, if the route name exist in route factory will push it from flutter, otherwise push a native page



    ```dart
    class BoostNavigator {
    ...
    Future<T> push<T extends Object>(String name,
    {Map<String, dynamic> arguments,
    bool withContainer = false,
    bool opaque = true}) async { ...
    if (isFlutterPage(pushOption.name)) {
    return appState.pushWithResult(pushOption.name,
    uniqueId: pushOption.uniqueId,
    arguments: pushOption.arguments,
    withContainer: withContainer,
    opaque: opaque);
    } else {
    final params = CommonParams()
    ..pageName = pushOption.name
    ..arguments = pushOption.arguments;
    appState.nativeRouterApi.pushNativeRoute(params);
    return appState.pendNativeResult(pushOption.name);
    }
    } else {
    assert(state.type == InterceptorResultType.resolve);
    return Future<T>.value(state.data as T);
    }
    });
    }



    /// consumer with above method `pushWithResult.pushWithResult`
    class FlutterBoostAppState extends State<FlutterBoostApp> {
    ...
    Future<T> pushWithResult<T extends Object>(String pageName, ..
    ///if with container is true, that mean flutter will call native to create new `FBFlutterContainer`, when this container appear, than call flutter to create a corresponding container in flutter end, then execution the sesion `Push a fluter page via native
    `
    if (withContainer) {
    ...
    nativeRouterApi.pushFlutterRoute(params);
    ...
    } else {
    /// if with container is false, then push flutter directly
    return pushPage(pageName, uniqueId: uniqueId, arguments: arguments);
    }
    }
    /// consumer with above method `pushPage`
    Future<T> pushPage<T extends Object>(String pageName,
    {String uniqueId, Map<String, dynamic> arguments}) {
    Logger.log('pushPage, uniqueId=$uniqueId, name=$pageName,'
    ' arguments:$arguments, $topContainer');
    final pageInfo = PageInfo(
    pageName: pageName,
    uniqueId: uniqueId ?? _createUniqueId(pageName),
    arguments: arguments,
    withContainer: false);
    assert(topContainer != null);
    return topContainer.addPage(BoostPage.create(pageInfo));
    }
    ```
    ```mermaid
    graph TB;
    A((tap))
    B[BoostNavigator]
    B1[AppState]
    C{is flutter page?}
    D{with container?}
    E[BoostDelegate]
    F[engine]
    G[UIViewController]
    G1[FBFlutterContainer]
     
    C-->|push native|F
    F-->|push native|E
    E-->|add cotnainer|G
    F-.->|push flutter|B1
    D-->|add page|BoostContainer
    A-->B-->|push|B1
    B1-->|push|C
    C-->D-.->|push container|F
    F-.->|push contianer|E
    E-.->G1
    G1-.->|push flutter|F
    ```
    **Note**:
    1. With container means notify native create a new FBFlutterContainer to hold on the flutterView, then reply flutter to add page in this container
    2. If the page name not found in route factory, will notify native to push a native page by the page name
    ## FlutterBoost native relationShip (base on iOS)
    ```mermaid
    graph LR;
    FlutterBoost-.-|listener|LifeCycle
    FlutterBoost-->FlutterEngine
    FlutterBoost-->FlutterBoostPlugin
    FlutterBoostPlugin-->FlutterBoostDelegate
    FlutterBoostPlugin-->FBFlutterRouteApi
    FlutterBoostPlugin-->FBFlutterContainerManager
    FlutterBoostPlugin-->FBEventListener
    FlutterBoostPlugin-->FBStackInfo
    FlutterBoostPlugin-.-|impl|FBNativeRouterApi
    FlutterBoostDelegate-.->FlutterEngine
    FBFlutterContainerManager-->|allContainers|FBFlutterViewContainer
    FBFlutterContainerManager-->|activeContainers 1..n|FBFlutterViewContainer
    FBFlutterViewContainer-.-|impl|FBFlutterContainer
    FlutterBoostPlugin-.-|listener lifecycle|FBFlutterViewContainer
    ```
    1. `FlutterBoost` combine other core instance and listener the lifeCycle events, manager the engine setup and destory, flutter also define the `Macro` to got the flutterBoost and current engine, plugin
    2. `FlutterBoostPlugin` delegate the flutter route events by `FlutterBoostDelegate`, send message to flutter whenever there route changed, so flutter end can update the widget
    3. `FBNativeRouterApi` listener flutter end route information open new native page via by the `FlutterBoostDelegate`
    4. `FBFlutterContainerManager` manager the containers that created or remove by the `FlutterBoostDelegate`
    5. `FBFlutterViewContainer` a container own the `FlutterView` show flutter page, each `FBFlutterViewContainer` corresponding to a `FlutterContianer` in flutter end, it will generated unique `BoostContainerWidget` to holds on the pages in current container with the navigator
    Note: The `FBFlutterViewContainer` provider the view lifcyle and flutter view, the `FlutterBoost` holds on current engine, the engine can assoicate with different `FBFlutterViewContainer`, with different containers, it can easy to show the flutter pages
    ## Flutter_Boost Dart Class Diagram Overivew

    ## Support
     
    https://github.com/alibaba/flutter_boost.git
  • 相关阅读:
    保护模式下通过写显存在屏幕上输出字符串
    Linux0.01 引导代码分析-head.s
    OpenGL Super Bible 第四章 Transform 程序绘图部分代码解析
    Ubuntu10.04 下编译 OpenOffice DEV300 分支
    今天把博客开通了,欢迎来访!
    沟通的工具ER图
    为什么博客叫秋水?
    mysql.基础笔记
    如何阅读别人的C代码
    Github搜索与查看
  • 原文地址:https://www.cnblogs.com/wwoo/p/15412176.html
Copyright © 2011-2022 走看看