docs

TOP(About this memo)) > 一覧(Flutter) > (参考)内部処理の理解(コードリーディング)

注意

表記

全体像



runApp実行時の流れ

import "package:flutter/widgets.dart";

main() {
  debugPrintScheduleFrameStacks = true;
  debugPrintBuildScope = true;
  debugPrint("before runApp");
  Future(() => debugPrint("future before runApp"));
  runApp(const MyWidget());
  debugPrint("after runApp");// 初回のツリーの構築はTimer.runにて実行されるため、initStateやbuildよりもこちらのprintが先に実行される。
  Future(() => debugPrint("future after runApp")); 
  Future.microtask(() => debugPrint("microtask after runtApp"));// Timer.runより早く実行される。
}

class MyWidget extends StatefulWidget {
  const MyWidget({super.key});

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {
    debugPrint("initState");
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    debugPrint("build");
    return const Placeholder();
  }
}

/*
flutter: before runApp
flutter: after runApp
flutter: microtask after runtApp
flutter: future before runApp
flutter: buildScope called with context [root](dirty); dirty list is: []
flutter: scheduleFrame() called. Current phase is SchedulerPhase.idle.
flutter: #0      debugPrintStack (package:flutter/src/foundation/assertions.dart:1201:29)
flutter: #1      SchedulerBinding.scheduleFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:875:9)
...
flutter: #25     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2835:19)
flutter: #26     RootWidget.attach (package:flutter/src/widgets/binding.dart:1255:13)
flutter: #27     WidgetsBinding.attachToBuildOwner (package:flutter/src/widgets/binding.dart:1083:27)
flutter: #28     WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:1065:5)
flutter: #29     WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:1051:7)
flutter: #33     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
flutter: (elided 3 frames from class _Timer and dart:async-patch)
flutter: initState
flutter: build
flutter: buildScope finished
flutter: future after runApp
*/

(IMO)フレームについて

ビルド(ツリーの構築)

Widget, Element, RenderObject

全体像



Element

StatefulElement/State

RootElement

RenderObject



InheritedElement/didChangedDependencies



レイアウト

(参考) ParentDataWidget



main() {
  testWidgets("", (tester) async {
    await tester.pumpWidget(Directionality(
        textDirection: TextDirection.ltr,
        child: Column(
          children: [Flexible(child: ListView())],
        )));
    debugDumpRenderTree();
  });
}
// ...
// child: RenderFlex#99a23
// ...
//  └─child 1: RenderRepaintBoundary#b97ba relayoutBoundary=up1
// ...
//     │ parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.loose

GlobalKey

その他

備忘: コードリーディング未済

(参考) Stand-alone widget tree with multiple render trees to enable multi-view rendering