• 添加输出代码的方式调试 Flutter 应用
    • Logging
    • Setting breakpoints
    • Debug flags: application layers
      • Widget tree
      • Render tree
      • Layer tree
      • Semantics tree
      • Scheduling
    • Debug flags: layout
    • Debugging animations
    • Debug flags: performance
      • Tracing Dart code performance
    • Performance overlay
    • Widget alignment grid

    添加输出代码的方式调试 Flutter 应用

    This doc describes debugging features that you can enable in code.For a full list of debugging and profiling tools, see theDebugging page.

    Logging

    备忘 You can view logs in DevTools’ Logging view or in your system console. This sections shows how to set up your logging statements.

    You have two options for logging for your application.The first is to use stdout and stderr.Generally, this is done using print() statements,or by importing dart:io and invoking methods onstderr and stdout. For example:

    1. stderr.writeln('print me');

    If you output too much at once, then Android sometimesdiscards some log lines. To avoid this, use debugPrint(),from Flutter’s foundation library. This is a wrapper around printthat throttles the output to a level that avoids being dropped byAndroid’s kernel.

    The other option for application logging is to use thedart:developer log() function. This allows you to include abit more granularity and information in the logging output.Here’s an example:

    1. import 'dart:developer' as developer;
    2. void main() {
    3. developer.log('log me', name: 'my.app.category');
    4. developer.log('log me 1', name: 'my.other.category');
    5. developer.log('log me 2', name: 'my.other.category');
    6. }

    You can also pass application data to the log call.The convention for this is to use the error: namedparameter on the log() call, JSON encode the objectyou want to send, and pass the encoded string to theerror parameter.

    1. import 'dart:convert';
    2. import 'dart:developer' as developer;
    3. void main() {
    4. var myCustomObject = ...;
    5. developer.log(
    6. 'log me',
    7. name: 'my.app.category',
    8. error: jsonEncode(myCustomObject),
    9. );
    10. }

    If viewing the logging output in DevTool’s logging view,the JSON encoded error param is interpreted as a data objectand rendered in the details view for that log entry.

    Setting breakpoints

    备忘 You can set breakpoints in DevTools’ Debugger, or in the built-in debugger of your IDE. If you want to set breakpoints programmatically, use the following instructions.

    You can insert programmatic breakpoints using thedebugger() statement. To use this, you have toimport the dart:developer package at the top ofthe relevant file.

    The debugger() statement takes an optional whenargument that you can specify to only break when acertain condition is true, as in the following example:

    1. import 'dart:developer';
    2. void someFunction(double offset) {
    3. debugger(when: offset > 30.0);
    4. // ...
    5. }

    Debug flags: application layers

    Each layer of the Flutter framework provides a function to dump itscurrent state or events to the console (using debugPrint).

    Widget tree

    To dump the state of the Widgets library, call debugDumpApp().You can call this more or less any time that the application is not inthe middle of running a build phase (in other words, not anywhere inside abuild() method), so long as the application has built at least once(in other words, any time after calling runApp()).

    For example, the following application:

    1. import 'package:flutter/material.dart';
    2. void main() {
    3. runApp(
    4. MaterialApp(
    5. home: AppHome(),
    6. ),
    7. );
    8. }
    9. class AppHome extends StatelessWidget {
    10. @override
    11. Widget build(BuildContext context) {
    12. return Material(
    13. child: Center(
    14. child: FlatButton(
    15. onPressed: () {
    16. debugDumpApp();
    17. },
    18. child: Text('Dump App'),
    19. ),
    20. ),
    21. );
    22. }
    23. }

    The prevous app outputs something like the following(the precise details vary by the version of the framework,the size of the device, and so forth):

    1. I/flutter ( 6559): WidgetsFlutterBinding - CHECKED MODE
    2. I/flutter ( 6559): RenderObjectToWidgetAdapter<RenderBox>([GlobalObjectKey RenderView(497039273)]; renderObject: RenderView)
    3. I/flutter ( 6559): MaterialApp(state: _MaterialAppState(1009803148))
    4. I/flutter ( 6559): ScrollConfiguration()
    5. I/flutter ( 6559): AnimatedTheme(duration: 200ms; state: _AnimatedThemeState(543295893; ticker inactive; ThemeDataTween(ThemeData(Brightness.light Color(0xff2196f3) etc...) null)))
    6. I/flutter ( 6559): Theme(ThemeData(Brightness.light Color(0xff2196f3) etc...))
    7. I/flutter ( 6559): WidgetsApp([GlobalObjectKey _MaterialAppState(1009803148)]; state: _WidgetsAppState(552902158))
    8. I/flutter ( 6559): CheckedModeBanner()
    9. I/flutter ( 6559): Banner()
    10. I/flutter ( 6559): CustomPaint(renderObject: RenderCustomPaint)
    11. I/flutter ( 6559): DefaultTextStyle(inherit: true; color: Color(0xd0ff0000); family: "monospace"; size: 48.0; weight: 900; decoration: double Color(0xffffff00) TextDecoration.underline)
    12. I/flutter ( 6559): MediaQuery(MediaQueryData(size: Size(411.4, 683.4), devicePixelRatio: 2.625, textScaleFactor: 1.0, padding: EdgeInsets(0.0, 24.0, 0.0, 0.0)))
    13. I/flutter ( 6559): LocaleQuery(null)
    14. I/flutter ( 6559): Title(color: Color(0xff2196f3))
    15. I/flutter ( 6559): Navigator([GlobalObjectKey<NavigatorState> _WidgetsAppState(552902158)]; state: NavigatorState(240327618; tracking 1 ticker))
    16. I/flutter ( 6559): Listener(listeners: down, up, cancel; behavior: defer-to-child; renderObject: RenderPointerListener)
    17. I/flutter ( 6559): AbsorbPointer(renderObject: RenderAbsorbPointer)
    18. I/flutter ( 6559): Focus([GlobalKey 489139594]; state: _FocusState(739584448))
    19. I/flutter ( 6559): Semantics(container: true; renderObject: RenderSemanticsAnnotations)
    20. I/flutter ( 6559): _FocusScope(this scope has focus; focused subscope: [GlobalObjectKey MaterialPageRoute<void>(875520219)])
    21. I/flutter ( 6559): Overlay([GlobalKey 199833992]; state: OverlayState(619367313; entries: [OverlayEntry@248818791(opaque: false; maintainState: false), OverlayEntry@837336156(opaque: false; maintainState: true)]))
    22. I/flutter ( 6559): _Theatre(renderObject: _RenderTheatre)
    23. I/flutter ( 6559): Stack(renderObject: RenderStack)
    24. I/flutter ( 6559): _OverlayEntry([GlobalKey 612888877]; state: _OverlayEntryState(739137453))
    25. I/flutter ( 6559): │└IgnorePointer(ignoring: false; renderObject: RenderIgnorePointer)
    26. I/flutter ( 6559): ModalBarrier()
    27. I/flutter ( 6559): Semantics(container: true; renderObject: RenderSemanticsAnnotations)
    28. I/flutter ( 6559): GestureDetector()
    29. I/flutter ( 6559): RawGestureDetector(state: RawGestureDetectorState(39068508; gestures: tap; behavior: opaque))
    30. I/flutter ( 6559): _GestureSemantics(renderObject: RenderSemanticsGestureHandler)
    31. I/flutter ( 6559): Listener(listeners: down; behavior: opaque; renderObject: RenderPointerListener)
    32. I/flutter ( 6559): ConstrainedBox(BoxConstraints(biggest); renderObject: RenderConstrainedBox)
    33. I/flutter ( 6559): _OverlayEntry([GlobalKey 727622716]; state: _OverlayEntryState(279971240))
    34. I/flutter ( 6559): _ModalScope([GlobalKey 816151164]; state: _ModalScopeState(875510645))
    35. I/flutter ( 6559): Focus([GlobalObjectKey MaterialPageRoute<void>(875520219)]; state: _FocusState(331487674))
    36. I/flutter ( 6559): Semantics(container: true; renderObject: RenderSemanticsAnnotations)
    37. I/flutter ( 6559): _FocusScope(this scope has focus)
    38. I/flutter ( 6559): Offstage(offstage: false; renderObject: RenderOffstage)
    39. I/flutter ( 6559): IgnorePointer(ignoring: false; renderObject: RenderIgnorePointer)
    40. I/flutter ( 6559): _MountainViewPageTransition(animation: AnimationController(⏭ 1.000; paused; for MaterialPageRoute<void>(/))➩ProxyAnimationCubic(0.40, 0.00, 0.20, 1.00)➩Tween<Offset>(Offset(0.0, 1.0) Offset(0.0, 0.0))➩Offset(0.0, 0.0); state: _AnimatedState(552160732))
    41. I/flutter ( 6559): SlideTransition(animation: AnimationController(⏭ 1.000; paused; for MaterialPageRoute<void>(/))➩ProxyAnimationCubic(0.40, 0.00, 0.20, 1.00)➩Tween<Offset>(Offset(0.0, 1.0) Offset(0.0, 0.0))➩Offset(0.0, 0.0); state: _AnimatedState(714726495))
    42. I/flutter ( 6559): FractionalTranslation(renderObject: RenderFractionalTranslation)
    43. I/flutter ( 6559): RepaintBoundary(renderObject: RenderRepaintBoundary)
    44. I/flutter ( 6559): PageStorage([GlobalKey 619728754])
    45. I/flutter ( 6559): _ModalScopeStatus(active)
    46. I/flutter ( 6559): AppHome()
    47. I/flutter ( 6559): Material(MaterialType.canvas; elevation: 0; state: _MaterialState(780114997))
    48. I/flutter ( 6559): AnimatedContainer(duration: 200ms; has background; state: _AnimatedContainerState(616063822; ticker inactive; has background))
    49. I/flutter ( 6559): Container(bg: BoxDecoration())
    50. I/flutter ( 6559): DecoratedBox(renderObject: RenderDecoratedBox)
    51. I/flutter ( 6559): Container(bg: BoxDecoration(backgroundColor: Color(0xfffafafa)))
    52. I/flutter ( 6559): DecoratedBox(renderObject: RenderDecoratedBox)
    53. I/flutter ( 6559): NotificationListener<LayoutChangedNotification>()
    54. I/flutter ( 6559): _InkFeature([GlobalKey ink renderer]; renderObject: _RenderInkFeatures)
    55. I/flutter ( 6559): AnimatedDefaultTextStyle(duration: 200ms; inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 400; baseline: alphabetic; state: _AnimatedDefaultTextStyleState(427742350; ticker inactive))
    56. I/flutter ( 6559): DefaultTextStyle(inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 400; baseline: alphabetic)
    57. I/flutter ( 6559): Center(alignment: Alignment.center; renderObject: RenderPositionedBox)
    58. I/flutter ( 6559): FlatButton()
    59. I/flutter ( 6559): MaterialButton(state: _MaterialButtonState(398724090))
    60. I/flutter ( 6559): ConstrainedBox(BoxConstraints(88.0<=w<=Infinity, h=36.0); renderObject: RenderConstrainedBox relayoutBoundary=up1)
    61. I/flutter ( 6559): AnimatedDefaultTextStyle(duration: 200ms; inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 500; baseline: alphabetic; state: _AnimatedDefaultTextStyleState(315134664; ticker inactive))
    62. I/flutter ( 6559): DefaultTextStyle(inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 500; baseline: alphabetic)
    63. I/flutter ( 6559): IconTheme(color: Color(0xdd000000))
    64. I/flutter ( 6559): InkWell(state: _InkResponseState<InkResponse>(369160267))
    65. I/flutter ( 6559): GestureDetector()
    66. I/flutter ( 6559): RawGestureDetector(state: RawGestureDetectorState(175370983; gestures: tap; behavior: opaque))
    67. I/flutter ( 6559): _GestureSemantics(renderObject: RenderSemanticsGestureHandler relayoutBoundary=up2)
    68. I/flutter ( 6559): Listener(listeners: down; behavior: opaque; renderObject: RenderPointerListener relayoutBoundary=up3)
    69. I/flutter ( 6559): Container(padding: EdgeInsets(16.0, 0.0, 16.0, 0.0))
    70. I/flutter ( 6559): Padding(renderObject: RenderPadding relayoutBoundary=up4)
    71. I/flutter ( 6559): Center(alignment: Alignment.center; widthFactor: 1.0; renderObject: RenderPositionedBox relayoutBoundary=up5)
    72. I/flutter ( 6559): Text("Dump App")
    73. I/flutter ( 6559): RichText(renderObject: RenderParagraph relayoutBoundary=up6)

    This is the “flattened” tree, showing all the widgets projectedthrough their various build functions. (This is the tree you obtain ifyou call toStringDeep() on the root of the widget tree.)You’ll see a lot of widgets in there that don’t appear in yourapplication’s source, because they are inserted by the framework’swidgets’ build functions. For example,InkFeature is an implementation detail of the Material widget.

    Since the debugDumpApp() call is invoked when the button changesfrom being pressed to being released, it coincides with theFlatButton object calling setState()and thus marking itself dirty. That is why, when you look at the dump youshould see that specific object marked as “dirty”. You can also see whatgesture listeners have been registered; in this case, a singleGestureDetector is listed, and it is listening only to a “tap” gesture(“tap” is the output of a TapGestureDetector’s toStringShortfunction).

    If you write your own widgets, you can add information by overridingdebugFillProperties(). Add [DiagnosticsProperty][[]objects to the method’s argument, and call the superclass method.This function is what the toString method uses to fill in thewidget’s description.

    Render tree

    If you are trying to debug a layout issue, then the Widgets layer’stree might be insufficiently detailed. In that case, you can dump therendering tree by calling debugDumpRenderTree().As with debugDumpApp(), you can call this more or less any timeexcept during a layout or paint phase. As a general rule,calling it from a frame callbackor an event handler is the best solution.

    To call debugDumpRenderTree(), you need to add import'package:flutter/rendering.dart'; to your source file.

    The output for the previous tiny example would look something likethe following:

    1. I/flutter ( 6559): RenderView
    2. I/flutter ( 6559): debug mode enabled - android
    3. I/flutter ( 6559): window size: Size(1080.0, 1794.0) (in physical pixels)
    4. I/flutter ( 6559): device pixel ratio: 2.625 (physical pixels per logical pixel)
    5. I/flutter ( 6559): configuration: Size(411.4, 683.4) at 2.625x (in logical pixels)
    6. I/flutter ( 6559):
    7. I/flutter ( 6559): └─child: RenderCustomPaint
    8. I/flutter ( 6559): creator: CustomPaint Banner CheckedModeBanner
    9. I/flutter ( 6559): WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)]
    10. I/flutter ( 6559): Theme AnimatedTheme ScrollConfiguration MaterialApp
    11. I/flutter ( 6559): [root]
    12. I/flutter ( 6559): parentData: <none>
    13. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    14. I/flutter ( 6559): size: Size(411.4, 683.4)
    15. I/flutter ( 6559):
    16. I/flutter ( 6559): └─child: RenderPointerListener
    17. I/flutter ( 6559): creator: Listener Navigator-[GlobalObjectKey<NavigatorState>
    18. I/flutter ( 6559): _WidgetsAppState(552902158)] Title LocaleQuery MediaQuery
    19. I/flutter ( 6559): DefaultTextStyle CustomPaint Banner CheckedModeBanner
    20. I/flutter ( 6559): WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)]
    21. I/flutter ( 6559): Theme AnimatedTheme
    22. I/flutter ( 6559): parentData: <none>
    23. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    24. I/flutter ( 6559): size: Size(411.4, 683.4)
    25. I/flutter ( 6559): behavior: defer-to-child
    26. I/flutter ( 6559): listeners: down, up, cancel
    27. I/flutter ( 6559):
    28. I/flutter ( 6559): └─child: RenderAbsorbPointer
    29. I/flutter ( 6559): creator: AbsorbPointer Listener
    30. I/flutter ( 6559): Navigator-[GlobalObjectKey<NavigatorState>
    31. I/flutter ( 6559): _WidgetsAppState(552902158)] Title LocaleQuery MediaQuery
    32. I/flutter ( 6559): DefaultTextStyle CustomPaint Banner CheckedModeBanner
    33. I/flutter ( 6559): WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)]
    34. I/flutter ( 6559): Theme
    35. I/flutter ( 6559): parentData: <none>
    36. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    37. I/flutter ( 6559): size: Size(411.4, 683.4)
    38. I/flutter ( 6559): absorbing: false
    39. I/flutter ( 6559):
    40. I/flutter ( 6559): └─child: RenderSemanticsAnnotations
    41. I/flutter ( 6559): creator: Semantics Focus-[GlobalKey 489139594] AbsorbPointer
    42. I/flutter ( 6559): Listener Navigator-[GlobalObjectKey<NavigatorState>
    43. I/flutter ( 6559): _WidgetsAppState(552902158)] Title LocaleQuery MediaQuery
    44. I/flutter ( 6559): DefaultTextStyle CustomPaint Banner CheckedModeBanner
    45. I/flutter ( 6559):
    46. I/flutter ( 6559): parentData: <none>
    47. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    48. I/flutter ( 6559): size: Size(411.4, 683.4)
    49. I/flutter ( 6559):
    50. I/flutter ( 6559): └─child: _RenderTheatre
    51. I/flutter ( 6559): creator: _Theatre Overlay-[GlobalKey 199833992] _FocusScope
    52. I/flutter ( 6559): Semantics Focus-[GlobalKey 489139594] AbsorbPointer
    53. I/flutter ( 6559): Listener Navigator-[GlobalObjectKey<NavigatorState>
    54. I/flutter ( 6559): _WidgetsAppState(552902158)] Title LocaleQuery MediaQuery
    55. I/flutter ( 6559): DefaultTextStyle
    56. I/flutter ( 6559): parentData: <none>
    57. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    58. I/flutter ( 6559): size: Size(411.4, 683.4)
    59. I/flutter ( 6559):
    60. I/flutter ( 6559): ├─onstage: RenderStack
    61. I/flutter ( 6559): creator: Stack _Theatre Overlay-[GlobalKey 199833992]
    62. I/flutter ( 6559): _FocusScope Semantics Focus-[GlobalKey 489139594]
    63. I/flutter ( 6559): AbsorbPointer Listener
    64. I/flutter ( 6559): Navigator-[GlobalObjectKey<NavigatorState>
    65. I/flutter ( 6559): _WidgetsAppState(552902158)] Title LocaleQuery MediaQuery
    66. I/flutter ( 6559):
    67. I/flutter ( 6559): parentData: not positioned; offset=Offset(0.0, 0.0)
    68. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    69. I/flutter ( 6559): size: Size(411.4, 683.4)
    70. I/flutter ( 6559):
    71. I/flutter ( 6559): ├─child 1: RenderIgnorePointer
    72. I/flutter ( 6559): creator: IgnorePointer _OverlayEntry-[GlobalKey 612888877]
    73. I/flutter ( 6559): Stack _Theatre Overlay-[GlobalKey 199833992] _FocusScope
    74. I/flutter ( 6559): Semantics Focus-[GlobalKey 489139594] AbsorbPointer
    75. I/flutter ( 6559): Listener Navigator-[GlobalObjectKey<NavigatorState>
    76. I/flutter ( 6559): _WidgetsAppState(552902158)] Title
    77. I/flutter ( 6559): parentData: not positioned; offset=Offset(0.0, 0.0)
    78. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    79. I/flutter ( 6559): size: Size(411.4, 683.4)
    80. I/flutter ( 6559): ignoring: false
    81. I/flutter ( 6559): ignoringSemantics: implicitly false
    82. I/flutter ( 6559):
    83. I/flutter ( 6559): └─child: RenderSemanticsAnnotations
    84. I/flutter ( 6559): creator: Semantics ModalBarrier IgnorePointer
    85. I/flutter ( 6559): _OverlayEntry-[GlobalKey 612888877] Stack _Theatre
    86. I/flutter ( 6559): Overlay-[GlobalKey 199833992] _FocusScope Semantics
    87. I/flutter ( 6559): Focus-[GlobalKey 489139594] AbsorbPointer Listener
    88. I/flutter ( 6559): parentData: <none>
    89. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    90. I/flutter ( 6559): size: Size(411.4, 683.4)
    91. I/flutter ( 6559):
    92. I/flutter ( 6559): └─child: RenderSemanticsGestureHandler
    93. I/flutter ( 6559): creator: _GestureSemantics RawGestureDetector GestureDetector
    94. I/flutter ( 6559): Semantics ModalBarrier IgnorePointer
    95. I/flutter ( 6559): _OverlayEntry-[GlobalKey 612888877] Stack _Theatre
    96. I/flutter ( 6559): Overlay-[GlobalKey 199833992] _FocusScope Semantics
    97. I/flutter ( 6559): parentData: <none>
    98. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    99. I/flutter ( 6559): size: Size(411.4, 683.4)
    100. I/flutter ( 6559):
    101. I/flutter ( 6559): └─child: RenderPointerListener
    102. I/flutter ( 6559): creator: Listener _GestureSemantics RawGestureDetector
    103. I/flutter ( 6559): GestureDetector Semantics ModalBarrier IgnorePointer
    104. I/flutter ( 6559): _OverlayEntry-[GlobalKey 612888877] Stack _Theatre
    105. I/flutter ( 6559): Overlay-[GlobalKey 199833992] _FocusScope
    106. I/flutter ( 6559): parentData: <none>
    107. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    108. I/flutter ( 6559): size: Size(411.4, 683.4)
    109. I/flutter ( 6559): behavior: opaque
    110. I/flutter ( 6559): listeners: down
    111. I/flutter ( 6559):
    112. I/flutter ( 6559): └─child: RenderConstrainedBox
    113. I/flutter ( 6559): creator: ConstrainedBox Listener _GestureSemantics
    114. I/flutter ( 6559): RawGestureDetector GestureDetector Semantics ModalBarrier
    115. I/flutter ( 6559): IgnorePointer _OverlayEntry-[GlobalKey 612888877] Stack
    116. I/flutter ( 6559): _Theatre Overlay-[GlobalKey 199833992]
    117. I/flutter ( 6559): parentData: <none>
    118. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    119. I/flutter ( 6559): size: Size(411.4, 683.4)
    120. I/flutter ( 6559): additionalConstraints: BoxConstraints(biggest)
    121. I/flutter ( 6559):
    122. I/flutter ( 6559): └─child 2: RenderSemanticsAnnotations
    123. I/flutter ( 6559): creator: Semantics Focus-[GlobalObjectKey
    124. I/flutter ( 6559): MaterialPageRoute<void>(875520219)] _ModalScope-[GlobalKey
    125. I/flutter ( 6559): 816151164] _OverlayEntry-[GlobalKey 727622716] Stack
    126. I/flutter ( 6559): _Theatre Overlay-[GlobalKey 199833992] _FocusScope
    127. I/flutter ( 6559): Semantics Focus-[GlobalKey 489139594] AbsorbPointer
    128. I/flutter ( 6559): Listener
    129. I/flutter ( 6559): parentData: not positioned; offset=Offset(0.0, 0.0)
    130. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    131. I/flutter ( 6559): size: Size(411.4, 683.4)
    132. I/flutter ( 6559):
    133. I/flutter ( 6559): └─child: RenderOffstage
    134. I/flutter ( 6559): creator: Offstage _FocusScope Semantics
    135. I/flutter ( 6559): Focus-[GlobalObjectKey MaterialPageRoute<void>(875520219)]
    136. I/flutter ( 6559): _ModalScope-[GlobalKey 816151164] _OverlayEntry-[GlobalKey
    137. I/flutter ( 6559): 727622716] Stack _Theatre Overlay-[GlobalKey 199833992]
    138. I/flutter ( 6559): _FocusScope Semantics Focus-[GlobalKey 489139594]
    139. I/flutter ( 6559): parentData: <none>
    140. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    141. I/flutter ( 6559): size: Size(411.4, 683.4)
    142. I/flutter ( 6559): offstage: false
    143. I/flutter ( 6559):
    144. I/flutter ( 6559): └─child: RenderIgnorePointer
    145. I/flutter ( 6559): creator: IgnorePointer Offstage _FocusScope Semantics
    146. I/flutter ( 6559): Focus-[GlobalObjectKey MaterialPageRoute<void>(875520219)]
    147. I/flutter ( 6559): _ModalScope-[GlobalKey 816151164] _OverlayEntry-[GlobalKey
    148. I/flutter ( 6559): 727622716] Stack _Theatre Overlay-[GlobalKey 199833992]
    149. I/flutter ( 6559): _FocusScope Semantics
    150. I/flutter ( 6559): parentData: <none>
    151. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    152. I/flutter ( 6559): size: Size(411.4, 683.4)
    153. I/flutter ( 6559): ignoring: false
    154. I/flutter ( 6559): ignoringSemantics: implicitly false
    155. I/flutter ( 6559):
    156. I/flutter ( 6559): └─child: RenderFractionalTranslation
    157. I/flutter ( 6559): creator: FractionalTranslation SlideTransition
    158. I/flutter ( 6559): _MountainViewPageTransition IgnorePointer Offstage
    159. I/flutter ( 6559): _FocusScope Semantics Focus-[GlobalObjectKey
    160. I/flutter ( 6559): MaterialPageRoute<void>(875520219)] _ModalScope-[GlobalKey
    161. I/flutter ( 6559): 816151164] _OverlayEntry-[GlobalKey 727622716] Stack
    162. I/flutter ( 6559): _Theatre
    163. I/flutter ( 6559): parentData: <none>
    164. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    165. I/flutter ( 6559): size: Size(411.4, 683.4)
    166. I/flutter ( 6559): translation: Offset(0.0, 0.0)
    167. I/flutter ( 6559): transformHitTests: true
    168. I/flutter ( 6559):
    169. I/flutter ( 6559): └─child: RenderRepaintBoundary
    170. I/flutter ( 6559): creator: RepaintBoundary FractionalTranslation
    171. I/flutter ( 6559): SlideTransition _MountainViewPageTransition IgnorePointer
    172. I/flutter ( 6559): Offstage _FocusScope Semantics Focus-[GlobalObjectKey
    173. I/flutter ( 6559): MaterialPageRoute<void>(875520219)] _ModalScope-[GlobalKey
    174. I/flutter ( 6559): 816151164] _OverlayEntry-[GlobalKey 727622716] Stack
    175. I/flutter ( 6559): parentData: <none>
    176. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    177. I/flutter ( 6559): size: Size(411.4, 683.4)
    178. I/flutter ( 6559): metrics: 83.3% useful (1 bad vs 5 good)
    179. I/flutter ( 6559): diagnosis: this is a useful repaint boundary and should be kept
    180. I/flutter ( 6559):
    181. I/flutter ( 6559): └─child: RenderDecoratedBox
    182. I/flutter ( 6559): creator: DecoratedBox Container AnimatedContainer Material
    183. I/flutter ( 6559): AppHome _ModalScopeStatus PageStorage-[GlobalKey
    184. I/flutter ( 6559): 619728754] RepaintBoundary FractionalTranslation
    185. I/flutter ( 6559): SlideTransition _MountainViewPageTransition IgnorePointer
    186. I/flutter ( 6559):
    187. I/flutter ( 6559): parentData: <none>
    188. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    189. I/flutter ( 6559): size: Size(411.4, 683.4)
    190. I/flutter ( 6559): decoration:
    191. I/flutter ( 6559): <no decorations specified>
    192. I/flutter ( 6559): configuration: ImageConfiguration(bundle:
    193. I/flutter ( 6559): PlatformAssetBundle@367106502(), devicePixelRatio: 2.625,
    194. I/flutter ( 6559): platform: android)
    195. I/flutter ( 6559):
    196. I/flutter ( 6559): └─child: RenderDecoratedBox
    197. I/flutter ( 6559): creator: DecoratedBox Container DecoratedBox Container
    198. I/flutter ( 6559): AnimatedContainer Material AppHome _ModalScopeStatus
    199. I/flutter ( 6559): PageStorage-[GlobalKey 619728754] RepaintBoundary
    200. I/flutter ( 6559): FractionalTranslation SlideTransition
    201. I/flutter ( 6559): parentData: <none>
    202. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    203. I/flutter ( 6559): size: Size(411.4, 683.4)
    204. I/flutter ( 6559): decoration:
    205. I/flutter ( 6559): backgroundColor: Color(0xfffafafa)
    206. I/flutter ( 6559): configuration: ImageConfiguration(bundle:
    207. I/flutter ( 6559): PlatformAssetBundle@367106502(), devicePixelRatio: 2.625,
    208. I/flutter ( 6559): platform: android)
    209. I/flutter ( 6559):
    210. I/flutter ( 6559): └─child: _RenderInkFeatures
    211. I/flutter ( 6559): creator: _InkFeature-[GlobalKey ink renderer]
    212. I/flutter ( 6559): NotificationListener<LayoutChangedNotification> DecoratedBox
    213. I/flutter ( 6559): Container DecoratedBox Container AnimatedContainer
    214. I/flutter ( 6559): Material AppHome _ModalScopeStatus PageStorage-[GlobalKey
    215. I/flutter ( 6559): 619728754] RepaintBoundary
    216. I/flutter ( 6559): parentData: <none>
    217. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    218. I/flutter ( 6559): size: Size(411.4, 683.4)
    219. I/flutter ( 6559):
    220. I/flutter ( 6559): └─child: RenderPositionedBox
    221. I/flutter ( 6559): creator: Center DefaultTextStyle AnimatedDefaultTextStyle
    222. I/flutter ( 6559): _InkFeature-[GlobalKey ink renderer]
    223. I/flutter ( 6559): NotificationListener<LayoutChangedNotification> DecoratedBox
    224. I/flutter ( 6559): Container DecoratedBox Container AnimatedContainer
    225. I/flutter ( 6559): Material AppHome
    226. I/flutter ( 6559): parentData: <none>
    227. I/flutter ( 6559): constraints: BoxConstraints(w=411.4, h=683.4)
    228. I/flutter ( 6559): size: Size(411.4, 683.4)
    229. I/flutter ( 6559): alignment: Alignment.center
    230. I/flutter ( 6559): widthFactor: expand
    231. I/flutter ( 6559): heightFactor: expand
    232. I/flutter ( 6559):
    233. I/flutter ( 6559): └─child: RenderConstrainedBox relayoutBoundary=up1
    234. I/flutter ( 6559): creator: ConstrainedBox MaterialButton FlatButton Center
    235. I/flutter ( 6559): DefaultTextStyle AnimatedDefaultTextStyle
    236. I/flutter ( 6559): _InkFeature-[GlobalKey ink renderer]
    237. I/flutter ( 6559): NotificationListener<LayoutChangedNotification> DecoratedBox
    238. I/flutter ( 6559): Container DecoratedBox Container
    239. I/flutter ( 6559): parentData: offset=Offset(156.7, 323.7)
    240. I/flutter ( 6559): constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=683.4)
    241. I/flutter ( 6559): size: Size(98.0, 36.0)
    242. I/flutter ( 6559): additionalConstraints: BoxConstraints(88.0<=w<=Infinity, h=36.0)
    243. I/flutter ( 6559):
    244. I/flutter ( 6559): └─child: RenderSemanticsGestureHandler relayoutBoundary=up2
    245. I/flutter ( 6559): creator: _GestureSemantics RawGestureDetector GestureDetector
    246. I/flutter ( 6559): InkWell IconTheme DefaultTextStyle
    247. I/flutter ( 6559): AnimatedDefaultTextStyle ConstrainedBox MaterialButton
    248. I/flutter ( 6559): FlatButton Center DefaultTextStyle
    249. I/flutter ( 6559): parentData: <none>
    250. I/flutter ( 6559): constraints: BoxConstraints(88.0<=w<=411.4, h=36.0)
    251. I/flutter ( 6559): size: Size(98.0, 36.0)
    252. I/flutter ( 6559):
    253. I/flutter ( 6559): └─child: RenderPointerListener relayoutBoundary=up3
    254. I/flutter ( 6559): creator: Listener _GestureSemantics RawGestureDetector
    255. I/flutter ( 6559): GestureDetector InkWell IconTheme DefaultTextStyle
    256. I/flutter ( 6559): AnimatedDefaultTextStyle ConstrainedBox MaterialButton
    257. I/flutter ( 6559): FlatButton Center
    258. I/flutter ( 6559): parentData: <none>
    259. I/flutter ( 6559): constraints: BoxConstraints(88.0<=w<=411.4, h=36.0)
    260. I/flutter ( 6559): size: Size(98.0, 36.0)
    261. I/flutter ( 6559): behavior: opaque
    262. I/flutter ( 6559): listeners: down
    263. I/flutter ( 6559):
    264. I/flutter ( 6559): └─child: RenderPadding relayoutBoundary=up4
    265. I/flutter ( 6559): creator: Padding Container Listener _GestureSemantics
    266. I/flutter ( 6559): RawGestureDetector GestureDetector InkWell IconTheme
    267. I/flutter ( 6559): DefaultTextStyle AnimatedDefaultTextStyle ConstrainedBox
    268. I/flutter ( 6559): MaterialButton
    269. I/flutter ( 6559): parentData: <none>
    270. I/flutter ( 6559): constraints: BoxConstraints(88.0<=w<=411.4, h=36.0)
    271. I/flutter ( 6559): size: Size(98.0, 36.0)
    272. I/flutter ( 6559): padding: EdgeInsets(16.0, 0.0, 16.0, 0.0)
    273. I/flutter ( 6559):
    274. I/flutter ( 6559): └─child: RenderPositionedBox relayoutBoundary=up5
    275. I/flutter ( 6559): creator: Center Padding Container Listener
    276. I/flutter ( 6559): _GestureSemantics RawGestureDetector GestureDetector
    277. I/flutter ( 6559): InkWell IconTheme DefaultTextStyle
    278. I/flutter ( 6559): AnimatedDefaultTextStyle ConstrainedBox
    279. I/flutter ( 6559): parentData: offset=Offset(16.0, 0.0)
    280. I/flutter ( 6559): constraints: BoxConstraints(56.0<=w<=379.4, h=36.0)
    281. I/flutter ( 6559): size: Size(66.0, 36.0)
    282. I/flutter ( 6559): alignment: Alignment.center
    283. I/flutter ( 6559): widthFactor: 1.0
    284. I/flutter ( 6559): heightFactor: expand
    285. I/flutter ( 6559):
    286. I/flutter ( 6559): └─child: RenderParagraph relayoutBoundary=up6
    287. I/flutter ( 6559): creator: RichText Text Center Padding Container
    288. I/flutter ( 6559): Listener _GestureSemantics RawGestureDetector
    289. I/flutter ( 6559): GestureDetector InkWell IconTheme DefaultTextStyle
    290. I/flutter ( 6559): parentData: offset=Offset(0.0, 10.0)
    291. I/flutter ( 6559): constraints: BoxConstraints(0.0<=w<=379.4, 0.0<=h<=36.0)
    292. I/flutter ( 6559): size: Size(66.0, 16.0)
    293. I/flutter ( 6559): ╘═╦══ text ═══
    294. I/flutter ( 6559): TextSpan:
    295. I/flutter ( 6559): inherit: false
    296. I/flutter ( 6559): color: Color(0xdd000000)
    297. I/flutter ( 6559): family: "Roboto"
    298. I/flutter ( 6559): size: 14.0
    299. I/flutter ( 6559): weight: 500
    300. I/flutter ( 6559): baseline: alphabetic
    301. I/flutter ( 6559): "Dump App"
    302. I/flutter ( 6559): ╚═══════════
    303. I/flutter ( 6559):
    304. I/flutter ( 6559): └╌no offstage children

    This is the output of the root RenderObject object’stoStringDeep() function.

    When debugging layout issues, the key fields to look at are thesize and constraints fields. The constraints flow down the tree,and the sizes flow back up.

    For example, in the previous dump you can see that the window size,Size(411.4, 683.4), is used to force all the boxes down to theRenderPositionedBox to be the size of the screen, withconstraints of BoxConstraints(w=411.4, h=683.4).The RenderPositionedBox, which the dump says was created by aCenter widget (as described by the creator field),sets its child’s constraints to a loose version of this:BoxConstraints(0.0<=w<=411.4, 0.0<=h<=683.4). The child, aRenderPadding, further inserts these constraints to ensurethere is room for the padding, and thus the [RenderConstrainedBox][]has a loose constraint of BoxConstraints(0.0<=w<=395.4,0.0<=h<=667.4). This object, which the creator field tells us isprobably part of the [FlatButton][]'s definition,sets a minimum width of 88 pixels on its contents and aspecific height of 36.0. (This is the FlatButton` class implementingthe Material Design guidelines regarding button dimensions.)

    The inner-most RenderPositionedBox loosens the constraints again,this time to center the text within the button. TheRenderParagraph picks its size based on its contents.If you now follow the sizes back up the chain,you’ll see how the text’s size is what influences thewidth of all the boxes that form the button, as they all take theirchild’s dimensions to size themselves.

    Another way to notice this is by looking at the “relayoutSubtreeRoot”part of the descriptions of each box, which essentially tells you howmany ancestors depend on this element’s size in some way.Thus the RenderParagraph has a relayoutSubtreeRoot=up8,meaning that when the RenderParagraph is dirtied,eight ancestors also have to be dirtied because they might beaffected by the new dimensions.

    If you write your own render objects, you can add information to thedump by overriding debugFillProperties().Add DiagnosticsPropertyobjects to the method’s argument, and call the superclass method.

    Layer tree

    If you are trying to debug a compositing issue, you can usedebugDumpLayerTree().For the previous example, it would output:

    1. I/flutter : TransformLayer
    2. I/flutter : creator: [root]
    3. I/flutter : offset: Offset(0.0, 0.0)
    4. I/flutter : transform:
    5. I/flutter : [0] 3.5,0.0,0.0,0.0
    6. I/flutter : [1] 0.0,3.5,0.0,0.0
    7. I/flutter : [2] 0.0,0.0,1.0,0.0
    8. I/flutter : [3] 0.0,0.0,0.0,1.0
    9. I/flutter :
    10. I/flutter : ├─child 1: OffsetLayer
    11. I/flutter : creator: RepaintBoundary _FocusScope Semantics Focus-[GlobalObjectKey MaterialPageRoute(560156430)] _ModalScope-[GlobalKey 328026813] _OverlayEntry-[GlobalKey 388965355] Stack Overlay-[GlobalKey 625702218] Navigator-[GlobalObjectKey _MaterialAppState(859106034)] Title
    12. I/flutter : offset: Offset(0.0, 0.0)
    13. I/flutter :
    14. I/flutter : └─child 1: PictureLayer
    15. I/flutter :
    16. I/flutter : └─child 2: PictureLayer

    This is the output of calling toStringDeep on the root Layer object.

    The transform at the root is the transform that applies the devicepixel ratio; in this case, a ratio of 3.5 device pixels for everylogical pixel.

    The RepaintBoundary widget, which creates a RenderRepaintBoundaryin the render tree, creates a new layer in the layer tree. This isused to reduce how much needs to be repainted.

    Semantics tree

    You can also obtain a dump of the Semantics tree(the tree presented to the system accessibility APIs) usingdebugDumpSemanticsTree(). To use this,you have to have first enable accessibility, for example, byenabling a system accessibility tool or the SemanticsDebugger.

    For the previous example, it would output the following:

    1. I/flutter : SemanticsNode(0; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
    2. I/flutter : SemanticsNode(1; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
    3. I/flutter : SemanticsNode(2; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4); canBeTapped)
    4. I/flutter : SemanticsNode(3; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4))
    5. I/flutter : SemanticsNode(4; Rect.fromLTRB(0.0, 0.0, 82.0, 36.0); canBeTapped; "Dump App")

    Scheduling

    To find out where your events happen relative to the frame’sbegin/end, you can toggle the debugPrintBeginFrameBannerand the debugPrintEndFrameBanner booleans to print thebeginning and end of the frames to the console.

    For example:

    1. I/flutter : ▄▄▄▄▄▄▄▄ Frame 12 30s 437.086ms ▄▄▄▄▄▄▄▄
    2. I/flutter : Debug print: Am I performing this work more than once per frame?
    3. I/flutter : Debug print: Am I performing this work more than once per frame?
    4. I/flutter : ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

    The debugPrintScheduleFrameStacks flag can also be usedto print the call stack causing the current frame to be scheduled.

    Debug flags: layout

    You can also debug a layout problem visually, by settingdebugPaintSizeEnabled to true.This is a boolean from the rendering library. It can beenabled at any time and affects all painting while it is true.The easiest way to set it is at the top of your void main()entry point. See an example in the following code:

    1. //add import to rendering library
    2. import 'package:flutter/rendering.dart';
    3. void main() {
    4. debugPaintSizeEnabled=true;
    5. runApp(MyApp());
    6. }

    When it is enabled, all boxes get a bright teal border,padding (from widgets like Padding) is shown in fadedblue with a darker blue box around the child, alignment(from widgets like Center and Align) is shown withyellow arrows, and spacers (from widgets likeContainer when they have no child) are shown in gray.

    The debugPaintBaselinesEnabled flagdoes something similar but for objects with baselines.The alphabetic baseline is shown in bright green and theideographic baseline in orange.

    The debugPaintPointersEnabled flag turns on aspecial mode whereby any objects that are being tappedget highlighted in teal. This can help you determinewhether an object is somehow failing to correctly hittest (which might happen if, for instance, it is actuallyoutside the bounds of its parent and thus notbeing considered for hit testing in the first place).

    If you’re trying to debug compositor layers, for exampleto determine whether and where to add RepaintBoundarywidgets, you can use the debugPaintLayerBordersEnabledflag, which outlines each layer’s bounds in orange,or the debugRepaintRainbowEnabled flag,which causes layers to be overlayed with a rotating set ofcolors whenever they are repainted.

    All of these flags only work in debug mode.In general, anything in the Flutter framework that starts with“debug…” only works in debug mode.

    Debugging animations

    备忘 The easiest way to debug animations is to slow them down. You can do this using the Slow Animations button in DevTools’ Inspector view, which slows down the animation by 5x. If you want more control over the amount of slowness, use the following instructions.

    Set the timeDilation variable (from the schedulerlibrary) to a number greater than 1.0, for instance, 50.0.It’s best to only set this once on app startup. If youchange it on the fly, especially if you reduce it whileanimations are running, it’s possible that the frameworkwill observe time going backwards, which will probablyresult in asserts and generally interfere with your efforts.

    Debug flags: performance

    备忘 You can achieve similar results to some of these debug flags using DevTools. Some of the debug flags aren’t particularly useful. If you find a flag that has functionality you would like to see added to DevTools, please file an issue.

    Flutter provides a wide variety of debug flags and functionsto help you debug your app at various points along thedevelopment cycle. To use these features, you must compilein debug mode. The following list, while not complete,highlights some of flags (and one function) from therendering library for debugging performance issues.

    You can set these flags either by editing the framework code,or by importing the module and setting the value in yourmain() method, following by a hot restart.

    • debugDumpRenderTree()
    • Call this function when not in a layout or repaint phase to dump the rendering tree to the console. (Pressing t from flutter run calls this command.) Search for “RepaintBoundary” to see diagnostics on how useful a boundary is.

    • debugPaintLayerBordersEnabled

    • PENDING

    • debugRepaintRainbowEnabled

    • You can enable this flag in the Flutter inspector by selecting the Repaint Rainbow button. If any static widgets are rotating through the colors of the rainbow (for example, a static header), those areas are candidates for adding repaint boundaries.

    • debugPrintMarkNeedsLayoutStacks

    • Enable this flag if you’re seeing more layouts than you expect (for example, on the timeline, on a profile, or from a print statement inside a layout method). Once enabled, the console is flooded with stack traces showing why each render object is being marked dirty for layout. You can use the debugPrintStack() method from the services library to print your own stack traces on demand, if this kind of approach is useful to you.

    • debugPrintMarkNeedsPaintStacks

    • Similar to debugPrintMarkNeedsLayoutStacks, but for excess painting. You can use the debugPrintStack() method from the services library to print your own stack traces on demand, if this kind of approach is useful to you.

    Tracing Dart code performance

    备忘 You can use the DevTools Timeline view to perform traces. You can also import and export trace files into the Timeline view, but only files generated by DevTools.

    To perform custom performance traces programmatically andmeasure wall/CPU time of arbitrary segments of Dart codesimilar to what would be done on Android with systrace,use dart:developer Timeline utilities to wrap thecode you want to measure such as:

    1. import 'dart:developer';
    2. Timeline.startSync('interesting function');
    3. // iWonderHowLongThisTakes();
    4. Timeline.finishSync();

    Then open your app’s Observatory’s timeline page, check the ‘Dart’recording option and perform the function you want to measure.

    Refreshing the page displays the chronological timeline recordsof your app in Chrome’s tracing tool.

    Be sure to run your app in profile mode to ensure that theruntime performance characteristics closely match that of yourfinal product.

    Performance overlay

    备忘 You can toggle display of the performance overlay on your app using the Performance Overlay button in the Flutter inspector. If you prefer to do it in code, use the following instructions.

    You can programmatically enable the PerformanceOverlay widget bysetting the showPerformanceOverlay property to true on theMaterialApp, CupertinoApp, or WidgetsAppconstructor:

    1. class MyApp extends StatelessWidget {
    2. @override
    3. Widget build(BuildContext context) {
    4. return MaterialApp(
    5. showPerformanceOverlay: true,
    6. title: 'My Awesome App',
    7. theme: ThemeData(
    8. primarySwatch: Colors.blue,
    9. ),
    10. home: MyHomePage(title: 'My Awesome App'),
    11. );
    12. }
    13. }

    (If you’re not using MaterialApp, CupertinoApp,or WidgetsApp, you can get the same effect by wrapping yourapplication in a stack and putting a widget on your stack that wascreated by calling PerformanceOverlay.allEnabled().)

    For information on how to interpret the graphs in the overlay,see The performance overlay inProfiling Flutter performance.

    Widget alignment grid

    You can programmatically overlay aMaterial Design baseline grid on top of your app tohelp verify alignments by using thedebugShowMaterialGrid argument in theMaterialApp constructor.

    In non-Material applications, you can achieve a similareffect by using a GridPaper widget directly.