以下分析基于 flutter_boost 分支 feature/flutter_1.9_androidx_upgrade
flutter_boost為了實現(xiàn)每個widget頁面都有一個native端的activity頁面與之對應(yīng)膀篮,那么打開新的flutter頁面時,就指定了特殊的打開頁面方式:
FlutterBoost.singleton.open();
這個函數(shù)的作用就是通知native端华蜒,開始創(chuàng)建activity。當native端來到了
setContentView(createFlutterView());
時忱辅,就會重新進入到flutter側(cè)的ContainerCoordinator類中的"didInitPageContainer"呈昔,其實此時并沒有實質(zhì)上的改變顶捷,就是創(chuàng)建了一個與ContainerLifeCycle.Init對應(yīng)的ContainerSettings。當native側(cè)的代碼進入到onResume()后翰蠢,又會發(fā)送事件進入到flutter側(cè)的"didShowPageContainer"项乒。此時開始了真正意義上的flutter頁面創(chuàng)建。
bool nativeContainerDidShow(String name, Map params, String pageId) {
FlutterBoost.containerManager
?.showContainer(_createContainerSettings(name, params, pageId));
performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Appear);
return true;
}
因此需要重點關(guān)注ContainerManager中的showContainer()梁沧。在這個方法中會先判斷_onStage是不是就是要顯示的頁面板丽,如果不是就從_offStage中查找。其中_onStage定義為當前正在顯示的頁面。_offStage是存放不是正在顯示的頁面的集合埃碱。如果在_offStage中查找不到猖辫,就會進入pushContainer()
void pushContainer(BoostContainerSettings settings) {
……
_offstage.add(_onstage);
_onstage = BoostContainer.obtain(widget.initNavigator, settings);
setState(() {});
……
}
這里新創(chuàng)建了一個BoostContainer。并且賦值給了_onStage砚殿,然后通過setStage()刷新widgetTree啃憎。由于重寫了setStage(),因此當調(diào)用進入setStage()之后似炎,又進入了_refreshOverlayEntries()辛萍。在該函數(shù)中
void _refreshOverlayEntries() {
final OverlayState overlayState = _overlayKey.currentState;
if (overlayState == null) {
return;
}
if (_leastEntries != null && _leastEntries.isNotEmpty) {
for (_ContainerOverlayEntry entry in _leastEntries) {
entry.remove();
}
}
final List<BoostContainer> containers = <BoostContainer>[];
containers.addAll(_offstage);
assert(_onstage != null, 'Should have a least one BoostContainer');
containers.add(_onstage);
_leastEntries = containers
.map<_ContainerOverlayEntry>(
(BoostContainer container) => _ContainerOverlayEntry(container))
.toList(growable: false);
///真正的頁面顯示是在這里
overlayState.insertAll(_leastEntries);
……
}
最后一行,真正意義上實現(xiàn)了頁面顯示羡藐。
overlayState.insertAll(_leastEntries);
overlayState是系統(tǒng)Navigator管理的overlay的狀態(tài)贩毕。但是我們自始至終都沒有使用Navigator啊,這個overlayState是如何生效的呢仆嗦?根據(jù)之前的分析我們了解到ContainerManager作為整個flutterModule的根root辉阶,然后提供給了MaterialApp。在ContainerManagerState的build方法中瘩扼,就是直接生成了一個overlay谆甜,返回給了整個flutter使用
@override
Widget build(BuildContext context) {
return Overlay(
key: _overlayKey,
initialEntries: const <OverlayEntry>[],
);
}
此時我們在_refreshOverlayEntries()中獲取的overlayState正是這個overlay的state。下面是整個流程的偽代碼
class MaterialApp{
//在main.dart中初始化FlutterBoost時返回的
builder:BoostContainerManager(initNavigator)
}
class BoostContainerManager{
builder:Overlay()
}
class _ContainerOverlayEntry extends OverlayEntry{
builder:BoostContainer.copyWith(initNavigator)
}
class BoostContainer extends Navigator{
BoostContainerSettings settings;
}
class BoostContainerSettings{
final WidgetBuilder builder;
//也就是我們在main.dart中注冊路由時使用的集绰。
builder:FlutterBoost.singleton.registerPageBuilders();
}