以下分析基于 flutter_boost 分支 feature/flutter_1.9_androidx_upgrade
flutter_boost為了實(shí)現(xiàn)每個(gè)widget頁(yè)面都有一個(gè)native端的activity頁(yè)面與之對(duì)應(yīng),那么打開(kāi)新的flutter頁(yè)面時(shí),就指定了特殊的打開(kāi)頁(yè)面方式:
FlutterBoost.singleton.open();
這個(gè)函數(shù)的作用就是通知native端,開(kāi)始創(chuàng)建activity。當(dāng)native端來(lái)到了
setContentView(createFlutterView());
時(shí),就會(huì)重新進(jìn)入到flutter側(cè)的ContainerCoordinator類(lèi)中的"didInitPageContainer",其實(shí)此時(shí)并沒(méi)有實(shí)質(zhì)上的改變,就是創(chuàng)建了一個(gè)與ContainerLifeCycle.Init對(duì)應(yīng)的ContainerSettings。當(dāng)native側(cè)的代碼進(jìn)入到onResume()后,又會(huì)發(fā)送事件進(jìn)入到flutter側(cè)的"didShowPageContainer"。此時(shí)開(kāi)始了真正意義上的flutter頁(yè)面創(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;
}
因此需要重點(diǎn)關(guān)注ContainerManager中的showContainer()。在這個(gè)方法中會(huì)先判斷_onStage是不是就是要顯示的頁(yè)面,如果不是就從_offStage中查找。其中_onStage定義為當(dāng)前正在顯示的頁(yè)面。_offStage是存放不是正在顯示的頁(yè)面的集合。如果在_offStage中查找不到,就會(huì)進(jìn)入pushContainer()
void pushContainer(BoostContainerSettings settings) {
……
_offstage.add(_onstage);
_onstage = BoostContainer.obtain(widget.initNavigator, settings);
setState(() {});
……
}
這里新創(chuàng)建了一個(gè)BoostContainer。并且賦值給了_onStage,然后通過(guò)setStage()刷新widgetTree。由于重寫(xiě)了setStage(),因此當(dāng)調(diào)用進(jìn)入setStage()之后,又進(jìn)入了_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);
///真正的頁(yè)面顯示是在這里
overlayState.insertAll(_leastEntries);
……
}
最后一行,真正意義上實(shí)現(xiàn)了頁(yè)面顯示。
overlayState.insertAll(_leastEntries);
overlayState是系統(tǒng)Navigator管理的overlay的狀態(tài)。但是我們自始至終都沒(méi)有使用Navigator啊,這個(gè)overlayState是如何生效的呢?根據(jù)之前的分析我們了解到ContainerManager作為整個(gè)flutterModule的根root,然后提供給了MaterialApp。在ContainerManagerState的build方法中,就是直接生成了一個(gè)overlay,返回給了整個(gè)flutter使用
@override
Widget build(BuildContext context) {
return Overlay(
key: _overlayKey,
initialEntries: const <OverlayEntry>[],
);
}
此時(shí)我們?cè)赺refreshOverlayEntries()中獲取的overlayState正是這個(gè)overlay的state。下面是整個(gè)流程的偽代碼
class MaterialApp{
//在main.dart中初始化FlutterBoost時(shí)返回的
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;
//也就是我們?cè)趍ain.dart中注冊(cè)路由時(shí)使用的。
builder:FlutterBoost.singleton.registerPageBuilders();
}