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

 

posted @ 2021-10-15 18:10  阿甘左  阅读(906)  评论(0编辑  收藏  举报