<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 調試Flutter應用 有各種各樣的工具和功能來幫助調試Flutter應用程序。 ## Dart 分析器 在運行應用程序前,請運行`flutter analyze`測試你的代碼。這個工具(它是`dartanalyzer`工具的一個包裝)將分析你的代碼并幫助你發現可能的錯誤。 如果你使用IntelliJ的Flutter插件,那么已經自動啟用了。 Dart分析器大量使用了代碼中的類型注釋來幫助追蹤問題。我們鼓勵您在任何地方使用它們(避免var、無類型的參數、無類型的列表文字等),因為這是追蹤問題的最快的方式。 ## Dart Observatory (語句級的單步調試和分析器) 如果您使用`flutter run`啟動應用程序,那么當它運行時,您可以打開Observatory URL的Web頁面(例如Observatory監聽<http://127.0.0.1:8100/>), 直接使用語句級單步調試器連接到您的應用程序。如果您使用的是IntelliJ,則還可以使用其內置的調試器來調試您的應用程序。 Observatory 同時支持分析、檢查堆等。有關Observatory的更多信息請參考[Observatory 文檔](https://dart-lang.github.io/observatory/). 如果您使用Observatory進行分析,請確保通過`--profile`選項來運行`flutter run`命令來運行應用程序。 否則,配置文件中將出現的主要問題將是調試斷言,以驗證框架的各種不變量(請參閱下面的“調試模式斷言”)。 ### `debugger()` 聲明 當使用Dart Observatory(或另一個Dart調試器,例如IntelliJ IDE中的調試器)時,可以使用該`debugger()`語句插入編程式斷點。要使用這個,你必須添加`import 'dart:developer';`到相關文件頂部。 `debugger()`語句采用一個可選`when`參數,您可以指定該參數僅在特定條件為真時中斷,如下所示: ``` void someFunction(double offset) { debugger(when: offset > 30.0); // ... } ``` ## `print`、`debugPrint`、`flutter logs` Dart `print()`功能將輸出到系統控制臺,您可以使用`flutter logs`了查看它(基本上是一個包裝`adb logcat`)。 如果你一次輸出太多,那么Android有時會丟棄一些日志行。為了避免這種情況,您可以使用Flutter的`foundation`庫中的[`debugPrint()`](https://docs.flutter.io/flutter/foundation/debugPrint.html)。 這是一個封裝print,它將輸出限制在一個級別,避免被Android內核丟棄。 Flutter框架中的許多類都有`toString`實現。按照慣例,這些輸出通常包括對象的`runtimeType`單行輸出,通常在表單中ClassName(more information about this instance…)。 樹中使用的一些類也具有`toStringDeep`,從該點返回整個子樹的多行描述。已一些具有詳細信息`toString`的類會實現一個`toStringShort`,它只返回對象的類型或其他非常簡短的(一個或兩個單詞)描述。 ## 調試模式斷言 在開發過程中,強烈建議您使用Flutter的“調試”模式,有時也稱為“checked”模式(注意:Dart2.0后“checked”被廢除,可以使用“strong” mode)。 如果您使用`flutter run`運行程序。在這種模式下,Dart assert語句被啟用,并且Flutter框架使用它來執行許多運行時檢查來驗證是否違反一些不可變的規則。 當一個不可變的規則被違反時,它被報告給控制臺,并帶有一些上下文信息來幫助追蹤問題的根源。 要關閉調試模式并使用發布模式,請使用`flutter run --release`運行您的應用程序。 這也關閉了Observatory調試器。一個中間模式可以關閉除Observatory之外所有調試輔助工具的,稱為“profile mode”,用`--profile`替代`--release`即可。 ## 調試應用程序層 Flutter框架的每一層都提供了將其當前狀態或事件轉儲(dump)到控制臺(使用`debugPrint`)的功能。 ### Widget 層 要轉儲Widgets庫的狀態,請調用[`debugDumpApp()`](https://docs.flutter.io/flutter/widgets/debugDumpApp.html)。 只要應用程序已經構建了至少一次(即在調用`build()`之后的任何時間),您可以在應用程序未處于構建階段(即,不在`build()`方法內調用 )的任何時間調用此方法(在調用`runApp()`之后)。 如, 這個應用程序: ``` import 'package:flutter/material.dart'; void main() { runApp( new MaterialApp( home: new AppHome(), ), ); } class AppHome extends StatelessWidget { @override Widget build(BuildContext context) { return new Material( child: new Center( child: new FlatButton( onPressed: () { debugDumpApp(); }, child: new Text('Dump App'), ), ), ); } } ``` …會輸出這樣的內容(精確的細節會根據框架的版本、設備的大小等等而變化): ``` I/flutter ( 6559): WidgetsFlutterBinding - CHECKED MODE I/flutter ( 6559): RenderObjectToWidgetAdapter<RenderBox>([GlobalObjectKey RenderView(497039273)]; renderObject: RenderView) I/flutter ( 6559): └MaterialApp(state: _MaterialAppState(1009803148)) I/flutter ( 6559): └ScrollConfiguration() I/flutter ( 6559): └AnimatedTheme(duration: 200ms; state: _AnimatedThemeState(543295893; ticker inactive; ThemeDataTween(ThemeData(Brightness.light Color(0xff2196f3) etc...) → null))) I/flutter ( 6559): └Theme(ThemeData(Brightness.light Color(0xff2196f3) etc...)) I/flutter ( 6559): └WidgetsApp([GlobalObjectKey _MaterialAppState(1009803148)]; state: _WidgetsAppState(552902158)) I/flutter ( 6559): └CheckedModeBanner() I/flutter ( 6559): └Banner() I/flutter ( 6559): └CustomPaint(renderObject: RenderCustomPaint) I/flutter ( 6559): └DefaultTextStyle(inherit: true; color: Color(0xd0ff0000); family: "monospace"; size: 48.0; weight: 900; decoration: double Color(0xffffff00) TextDecoration.underline) 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))) I/flutter ( 6559): └LocaleQuery(null) I/flutter ( 6559): └Title(color: Color(0xff2196f3)) I/flutter ( 6559): └Navigator([GlobalObjectKey<NavigatorState> _WidgetsAppState(552902158)]; state: NavigatorState(240327618; tracking 1 ticker)) I/flutter ( 6559): └Listener(listeners: down, up, cancel; behavior: defer-to-child; renderObject: RenderPointerListener) I/flutter ( 6559): └AbsorbPointer(renderObject: RenderAbsorbPointer) I/flutter ( 6559): └Focus([GlobalKey 489139594]; state: _FocusState(739584448)) I/flutter ( 6559): └Semantics(container: true; renderObject: RenderSemanticsAnnotations) I/flutter ( 6559): └_FocusScope(this scope has focus; focused subscope: [GlobalObjectKey MaterialPageRoute<Null>(875520219)]) I/flutter ( 6559): └Overlay([GlobalKey 199833992]; state: OverlayState(619367313; entries: [OverlayEntry@248818791(opaque: false; maintainState: false), OverlayEntry@837336156(opaque: false; maintainState: true)])) I/flutter ( 6559): └_Theatre(renderObject: _RenderTheatre) I/flutter ( 6559): └Stack(renderObject: RenderStack) I/flutter ( 6559): ├_OverlayEntry([GlobalKey 612888877]; state: _OverlayEntryState(739137453)) I/flutter ( 6559): │└IgnorePointer(ignoring: false; renderObject: RenderIgnorePointer) I/flutter ( 6559): │ └ModalBarrier() I/flutter ( 6559): │ └Semantics(container: true; renderObject: RenderSemanticsAnnotations) I/flutter ( 6559): │ └GestureDetector() I/flutter ( 6559): │ └RawGestureDetector(state: RawGestureDetectorState(39068508; gestures: tap; behavior: opaque)) I/flutter ( 6559): │ └_GestureSemantics(renderObject: RenderSemanticsGestureHandler) I/flutter ( 6559): │ └Listener(listeners: down; behavior: opaque; renderObject: RenderPointerListener) I/flutter ( 6559): │ └ConstrainedBox(BoxConstraints(biggest); renderObject: RenderConstrainedBox) I/flutter ( 6559): └_OverlayEntry([GlobalKey 727622716]; state: _OverlayEntryState(279971240)) I/flutter ( 6559): └_ModalScope([GlobalKey 816151164]; state: _ModalScopeState(875510645)) I/flutter ( 6559): └Focus([GlobalObjectKey MaterialPageRoute<Null>(875520219)]; state: _FocusState(331487674)) I/flutter ( 6559): └Semantics(container: true; renderObject: RenderSemanticsAnnotations) I/flutter ( 6559): └_FocusScope(this scope has focus) I/flutter ( 6559): └Offstage(offstage: false; renderObject: RenderOffstage) I/flutter ( 6559): └IgnorePointer(ignoring: false; renderObject: RenderIgnorePointer) I/flutter ( 6559): └_MountainViewPageTransition(animation: AnimationController(? 1.000; paused; for MaterialPageRoute<Null>(/))?ProxyAnimation?Cubic(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)) I/flutter ( 6559): └SlideTransition(animation: AnimationController(? 1.000; paused; for MaterialPageRoute<Null>(/))?ProxyAnimation?Cubic(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)) I/flutter ( 6559): └FractionalTranslation(renderObject: RenderFractionalTranslation) I/flutter ( 6559): └RepaintBoundary(renderObject: RenderRepaintBoundary) I/flutter ( 6559): └PageStorage([GlobalKey 619728754]) I/flutter ( 6559): └_ModalScopeStatus(active) I/flutter ( 6559): └AppHome() I/flutter ( 6559): └Material(MaterialType.canvas; elevation: 0; state: _MaterialState(780114997)) I/flutter ( 6559): └AnimatedContainer(duration: 200ms; has background; state: _AnimatedContainerState(616063822; ticker inactive; has background)) I/flutter ( 6559): └Container(bg: BoxDecoration()) I/flutter ( 6559): └DecoratedBox(renderObject: RenderDecoratedBox) I/flutter ( 6559): └Container(bg: BoxDecoration(backgroundColor: Color(0xfffafafa))) I/flutter ( 6559): └DecoratedBox(renderObject: RenderDecoratedBox) I/flutter ( 6559): └NotificationListener<LayoutChangedNotification>() I/flutter ( 6559): └_InkFeature([GlobalKey ink renderer]; renderObject: _RenderInkFeatures) 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)) I/flutter ( 6559): └DefaultTextStyle(inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 400; baseline: alphabetic) I/flutter ( 6559): └Center(alignment: Alignment.center; renderObject: RenderPositionedBox) I/flutter ( 6559): └FlatButton() I/flutter ( 6559): └MaterialButton(state: _MaterialButtonState(398724090)) I/flutter ( 6559): └ConstrainedBox(BoxConstraints(88.0<=w<=Infinity, h=36.0); renderObject: RenderConstrainedBox relayoutBoundary=up1) 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)) I/flutter ( 6559): └DefaultTextStyle(inherit: false; color: Color(0xdd000000); family: "Roboto"; size: 14.0; weight: 500; baseline: alphabetic) I/flutter ( 6559): └IconTheme(color: Color(0xdd000000)) I/flutter ( 6559): └InkWell(state: _InkResponseState<InkResponse>(369160267)) I/flutter ( 6559): └GestureDetector() I/flutter ( 6559): └RawGestureDetector(state: RawGestureDetectorState(175370983; gestures: tap; behavior: opaque)) I/flutter ( 6559): └_GestureSemantics(renderObject: RenderSemanticsGestureHandler relayoutBoundary=up2) I/flutter ( 6559): └Listener(listeners: down; behavior: opaque; renderObject: RenderPointerListener relayoutBoundary=up3) I/flutter ( 6559): └Container(padding: EdgeInsets(16.0, 0.0, 16.0, 0.0)) I/flutter ( 6559): └Padding(renderObject: RenderPadding relayoutBoundary=up4) I/flutter ( 6559): └Center(alignment: Alignment.center; widthFactor: 1.0; renderObject: RenderPositionedBox relayoutBoundary=up5) I/flutter ( 6559): └Text("Dump App") I/flutter ( 6559): └RichText(renderObject: RenderParagraph relayoutBoundary=up6) ``` 這是一個“扁平化”的樹,顯示了通過各種構建函數投影的所有widget(如果你在widget樹的根中調用`toStringDeepwidget`,這是你獲得的樹)。 你會看到很多在你的應用源代碼中沒有出現的widget,因為它們是被框架中widget的`build()`函數插入的。例如,[`InkFeature`](https://docs.flutter.io/flutter/material/InkFeature-class.html)是Material widget的一個實現細節 。 當按鈕從被按下變為被釋放時debugDumpApp()被調用,FlatButton對象同時調用`setState()`,并將自己標記為"dirty"。 這就是為什么如果你看轉儲,你會看到特定的對象標記為“dirty”。您還可以查看已注冊了哪些手勢監聽器; 在這種情況下,一個單一的GestureDetector被列出,并且監聽“tap”手勢(“tap”是`TapGestureDetector`的`toStringShort`函數輸出的) 如果您編寫自己的widget,則可以通過覆蓋[`debugFillProperties()`](https://docs.flutter.io/flutter/widgets/Widget/debugFillProperties.html)來添加信息。 將[DiagnosticsProperty](https://docs.flutter.io/flutter/foundation/DiagnosticsProperty-class.html)對象作為方法參數,并調用父類方法。 該函數是該`toString`方法用來填充小部件描述信息的。 ### 渲染層 如果您嘗試調試布局問題,那么Widgets層的樹可能不夠詳細。在這種情況下,您可以通過調用`debugDumpRenderTree()`轉儲渲染樹。 正如`debugDumpApp()`,除布局或繪制階段外,您可以隨時調用此函數。作為一般規則,從[frame 回調](https://docs.flutter.io/flutter/scheduler/SchedulerBinding/addPersistentFrameCallback.html) 或事件處理器中調用它是最佳解決方案。 要調用`debugDumpRenderTree()`,您需要添加`import'package:flutter/rendering.dart';`到您的源文件。 上面這個小例子的輸出結果如下所示: ``` I/flutter ( 6559): RenderView I/flutter ( 6559): │ debug mode enabled - android I/flutter ( 6559): │ window size: Size(1080.0, 1794.0) (in physical pixels) I/flutter ( 6559): │ device pixel ratio: 2.625 (physical pixels per logical pixel) I/flutter ( 6559): │ configuration: Size(411.4, 683.4) at 2.625x (in logical pixels) I/flutter ( 6559): │ I/flutter ( 6559): └─child: RenderCustomPaint I/flutter ( 6559): │ creator: CustomPaint ← Banner ← CheckedModeBanner ← I/flutter ( 6559): │ WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ← I/flutter ( 6559): │ Theme ← AnimatedTheme ← ScrollConfiguration ← MaterialApp ← I/flutter ( 6559): │ [root] I/flutter ( 6559): │ parentData: <none> I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): │ size: Size(411.4, 683.4) I/flutter ( 6559): │ I/flutter ( 6559): └─child: RenderPointerListener I/flutter ( 6559): │ creator: Listener ← Navigator-[GlobalObjectKey<NavigatorState> I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery I/flutter ( 6559): │ ← DefaultTextStyle ← CustomPaint ← Banner ← CheckedModeBanner ← I/flutter ( 6559): │ WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ← I/flutter ( 6559): │ Theme ← AnimatedTheme ← ? I/flutter ( 6559): │ parentData: <none> I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): │ size: Size(411.4, 683.4) I/flutter ( 6559): │ behavior: defer-to-child I/flutter ( 6559): │ listeners: down, up, cancel I/flutter ( 6559): │ I/flutter ( 6559): └─child: RenderAbsorbPointer I/flutter ( 6559): │ creator: AbsorbPointer ← Listener ← I/flutter ( 6559): │ Navigator-[GlobalObjectKey<NavigatorState> I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery I/flutter ( 6559): │ ← DefaultTextStyle ← CustomPaint ← Banner ← CheckedModeBanner ← I/flutter ( 6559): │ WidgetsApp-[GlobalObjectKey _MaterialAppState(1009803148)] ← I/flutter ( 6559): │ Theme ← ? I/flutter ( 6559): │ parentData: <none> I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): │ size: Size(411.4, 683.4) I/flutter ( 6559): │ absorbing: false I/flutter ( 6559): │ I/flutter ( 6559): └─child: RenderSemanticsAnnotations I/flutter ( 6559): │ creator: Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer I/flutter ( 6559): │ ← Listener ← Navigator-[GlobalObjectKey<NavigatorState> I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery I/flutter ( 6559): │ ← DefaultTextStyle ← CustomPaint ← Banner ← CheckedModeBanner ← I/flutter ( 6559): │ ? I/flutter ( 6559): │ parentData: <none> I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): │ size: Size(411.4, 683.4) I/flutter ( 6559): │ I/flutter ( 6559): └─child: _RenderTheatre I/flutter ( 6559): │ creator: _Theatre ← Overlay-[GlobalKey 199833992] ← _FocusScope ← I/flutter ( 6559): │ Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer ← I/flutter ( 6559): │ Listener ← Navigator-[GlobalObjectKey<NavigatorState> I/flutter ( 6559): │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery I/flutter ( 6559): │ ← DefaultTextStyle ← ? I/flutter ( 6559): │ parentData: <none> I/flutter ( 6559): │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): │ size: Size(411.4, 683.4) I/flutter ( 6559): │ I/flutter ( 6559): ├─onstage: RenderStack I/flutter ( 6559): ? │ creator: Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ← I/flutter ( 6559): ? │ _FocusScope ← Semantics ← Focus-[GlobalKey 489139594] ← I/flutter ( 6559): ? │ AbsorbPointer ← Listener ← I/flutter ( 6559): ? │ Navigator-[GlobalObjectKey<NavigatorState> I/flutter ( 6559): ? │ _WidgetsAppState(552902158)] ← Title ← LocaleQuery ← MediaQuery I/flutter ( 6559): ? │ ← ? I/flutter ( 6559): ? │ parentData: not positioned; offset=Offset(0.0, 0.0) I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ I/flutter ( 6559): ? ├─child 1: RenderIgnorePointer I/flutter ( 6559): ? │ │ creator: IgnorePointer ← _OverlayEntry-[GlobalKey 612888877] ← I/flutter ( 6559): ? │ │ Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ← _FocusScope I/flutter ( 6559): ? │ │ ← Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer ← I/flutter ( 6559): ? │ │ Listener ← Navigator-[GlobalObjectKey<NavigatorState> I/flutter ( 6559): ? │ │ _WidgetsAppState(552902158)] ← Title ← ? I/flutter ( 6559): ? │ │ parentData: not positioned; offset=Offset(0.0, 0.0) I/flutter ( 6559): ? │ │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ │ ignoring: false I/flutter ( 6559): ? │ │ ignoringSemantics: implicitly false I/flutter ( 6559): ? │ │ I/flutter ( 6559): ? │ └─child: RenderSemanticsAnnotations I/flutter ( 6559): ? │ │ creator: Semantics ← ModalBarrier ← IgnorePointer ← I/flutter ( 6559): ? │ │ _OverlayEntry-[GlobalKey 612888877] ← Stack ← _Theatre ← I/flutter ( 6559): ? │ │ Overlay-[GlobalKey 199833992] ← _FocusScope ← Semantics ← I/flutter ( 6559): ? │ │ Focus-[GlobalKey 489139594] ← AbsorbPointer ← Listener ← ? I/flutter ( 6559): ? │ │ parentData: <none> I/flutter ( 6559): ? │ │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ │ I/flutter ( 6559): ? │ └─child: RenderSemanticsGestureHandler I/flutter ( 6559): ? │ │ creator: _GestureSemantics ← RawGestureDetector ← GestureDetector I/flutter ( 6559): ? │ │ ← Semantics ← ModalBarrier ← IgnorePointer ← I/flutter ( 6559): ? │ │ _OverlayEntry-[GlobalKey 612888877] ← Stack ← _Theatre ← I/flutter ( 6559): ? │ │ Overlay-[GlobalKey 199833992] ← _FocusScope ← Semantics ← ? I/flutter ( 6559): ? │ │ parentData: <none> I/flutter ( 6559): ? │ │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ │ I/flutter ( 6559): ? │ └─child: RenderPointerListener I/flutter ( 6559): ? │ │ creator: Listener ← _GestureSemantics ← RawGestureDetector ← I/flutter ( 6559): ? │ │ GestureDetector ← Semantics ← ModalBarrier ← IgnorePointer ← I/flutter ( 6559): ? │ │ _OverlayEntry-[GlobalKey 612888877] ← Stack ← _Theatre ← I/flutter ( 6559): ? │ │ Overlay-[GlobalKey 199833992] ← _FocusScope ← ? I/flutter ( 6559): ? │ │ parentData: <none> I/flutter ( 6559): ? │ │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ │ behavior: opaque I/flutter ( 6559): ? │ │ listeners: down I/flutter ( 6559): ? │ │ I/flutter ( 6559): ? │ └─child: RenderConstrainedBox I/flutter ( 6559): ? │ creator: ConstrainedBox ← Listener ← _GestureSemantics ← I/flutter ( 6559): ? │ RawGestureDetector ← GestureDetector ← Semantics ← ModalBarrier I/flutter ( 6559): ? │ ← IgnorePointer ← _OverlayEntry-[GlobalKey 612888877] ← Stack ← I/flutter ( 6559): ? │ _Theatre ← Overlay-[GlobalKey 199833992] ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ additionalConstraints: BoxConstraints(biggest) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child 2: RenderSemanticsAnnotations I/flutter ( 6559): ? │ creator: Semantics ← Focus-[GlobalObjectKey I/flutter ( 6559): ? │ MaterialPageRoute<Null>(875520219)] ← _ModalScope-[GlobalKey I/flutter ( 6559): ? │ 816151164] ← _OverlayEntry-[GlobalKey 727622716] ← Stack ← I/flutter ( 6559): ? │ _Theatre ← Overlay-[GlobalKey 199833992] ← _FocusScope ← I/flutter ( 6559): ? │ Semantics ← Focus-[GlobalKey 489139594] ← AbsorbPointer ← I/flutter ( 6559): ? │ Listener ← ? I/flutter ( 6559): ? │ parentData: not positioned; offset=Offset(0.0, 0.0) I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderOffstage I/flutter ( 6559): ? │ creator: Offstage ← _FocusScope ← Semantics ← I/flutter ( 6559): ? │ Focus-[GlobalObjectKey MaterialPageRoute<Null>(875520219)] ← I/flutter ( 6559): ? │ _ModalScope-[GlobalKey 816151164] ← _OverlayEntry-[GlobalKey I/flutter ( 6559): ? │ 727622716] ← Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ← I/flutter ( 6559): ? │ _FocusScope ← Semantics ← Focus-[GlobalKey 489139594] ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ offstage: false I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderIgnorePointer I/flutter ( 6559): ? │ creator: IgnorePointer ← Offstage ← _FocusScope ← Semantics ← I/flutter ( 6559): ? │ Focus-[GlobalObjectKey MaterialPageRoute<Null>(875520219)] ← I/flutter ( 6559): ? │ _ModalScope-[GlobalKey 816151164] ← _OverlayEntry-[GlobalKey I/flutter ( 6559): ? │ 727622716] ← Stack ← _Theatre ← Overlay-[GlobalKey 199833992] ← I/flutter ( 6559): ? │ _FocusScope ← Semantics ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ ignoring: false I/flutter ( 6559): ? │ ignoringSemantics: implicitly false I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderFractionalTranslation I/flutter ( 6559): ? │ creator: FractionalTranslation ← SlideTransition ← I/flutter ( 6559): ? │ _MountainViewPageTransition ← IgnorePointer ← Offstage ← I/flutter ( 6559): ? │ _FocusScope ← Semantics ← Focus-[GlobalObjectKey I/flutter ( 6559): ? │ MaterialPageRoute<Null>(875520219)] ← _ModalScope-[GlobalKey I/flutter ( 6559): ? │ 816151164] ← _OverlayEntry-[GlobalKey 727622716] ← Stack ← I/flutter ( 6559): ? │ _Theatre ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ translation: Offset(0.0, 0.0) I/flutter ( 6559): ? │ transformHitTests: true I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderRepaintBoundary I/flutter ( 6559): ? │ creator: RepaintBoundary ← FractionalTranslation ← I/flutter ( 6559): ? │ SlideTransition ← _MountainViewPageTransition ← IgnorePointer ← I/flutter ( 6559): ? │ Offstage ← _FocusScope ← Semantics ← Focus-[GlobalObjectKey I/flutter ( 6559): ? │ MaterialPageRoute<Null>(875520219)] ← _ModalScope-[GlobalKey I/flutter ( 6559): ? │ 816151164] ← _OverlayEntry-[GlobalKey 727622716] ← Stack ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ metrics: 83.3% useful (1 bad vs 5 good) I/flutter ( 6559): ? │ diagnosis: this is a useful repaint boundary and should be kept I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderDecoratedBox I/flutter ( 6559): ? │ creator: DecoratedBox ← Container ← AnimatedContainer ← Material I/flutter ( 6559): ? │ ← AppHome ← _ModalScopeStatus ← PageStorage-[GlobalKey I/flutter ( 6559): ? │ 619728754] ← RepaintBoundary ← FractionalTranslation ← I/flutter ( 6559): ? │ SlideTransition ← _MountainViewPageTransition ← IgnorePointer ← I/flutter ( 6559): ? │ ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ decoration: I/flutter ( 6559): ? │ <no decorations specified> I/flutter ( 6559): ? │ configuration: ImageConfiguration(bundle: I/flutter ( 6559): ? │ PlatformAssetBundle@367106502(), devicePixelRatio: 2.625, I/flutter ( 6559): ? │ platform: android) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderDecoratedBox I/flutter ( 6559): ? │ creator: DecoratedBox ← Container ← DecoratedBox ← Container ← I/flutter ( 6559): ? │ AnimatedContainer ← Material ← AppHome ← _ModalScopeStatus ← I/flutter ( 6559): ? │ PageStorage-[GlobalKey 619728754] ← RepaintBoundary ← I/flutter ( 6559): ? │ FractionalTranslation ← SlideTransition ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ decoration: I/flutter ( 6559): ? │ backgroundColor: Color(0xfffafafa) I/flutter ( 6559): ? │ configuration: ImageConfiguration(bundle: I/flutter ( 6559): ? │ PlatformAssetBundle@367106502(), devicePixelRatio: 2.625, I/flutter ( 6559): ? │ platform: android) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: _RenderInkFeatures I/flutter ( 6559): ? │ creator: _InkFeature-[GlobalKey ink renderer] ← I/flutter ( 6559): ? │ NotificationListener<LayoutChangedNotification> ← DecoratedBox I/flutter ( 6559): ? │ ← Container ← DecoratedBox ← Container ← AnimatedContainer ← I/flutter ( 6559): ? │ Material ← AppHome ← _ModalScopeStatus ← PageStorage-[GlobalKey I/flutter ( 6559): ? │ 619728754] ← RepaintBoundary ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderPositionedBox I/flutter ( 6559): ? │ creator: Center ← DefaultTextStyle ← AnimatedDefaultTextStyle ← I/flutter ( 6559): ? │ _InkFeature-[GlobalKey ink renderer] ← I/flutter ( 6559): ? │ NotificationListener<LayoutChangedNotification> ← DecoratedBox I/flutter ( 6559): ? │ ← Container ← DecoratedBox ← Container ← AnimatedContainer ← I/flutter ( 6559): ? │ Material ← AppHome ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(w=411.4, h=683.4) I/flutter ( 6559): ? │ size: Size(411.4, 683.4) I/flutter ( 6559): ? │ alignment: Alignment.center I/flutter ( 6559): ? │ widthFactor: expand I/flutter ( 6559): ? │ heightFactor: expand I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderConstrainedBox relayoutBoundary=up1 I/flutter ( 6559): ? │ creator: ConstrainedBox ← MaterialButton ← FlatButton ← Center ← I/flutter ( 6559): ? │ DefaultTextStyle ← AnimatedDefaultTextStyle ← I/flutter ( 6559): ? │ _InkFeature-[GlobalKey ink renderer] ← I/flutter ( 6559): ? │ NotificationListener<LayoutChangedNotification> ← DecoratedBox I/flutter ( 6559): ? │ ← Container ← DecoratedBox ← Container ← ? I/flutter ( 6559): ? │ parentData: offset=Offset(156.7, 323.7) I/flutter ( 6559): ? │ constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=683.4) I/flutter ( 6559): ? │ size: Size(98.0, 36.0) I/flutter ( 6559): ? │ additionalConstraints: BoxConstraints(88.0<=w<=Infinity, h=36.0) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderSemanticsGestureHandler relayoutBoundary=up2 I/flutter ( 6559): ? │ creator: _GestureSemantics ← RawGestureDetector ← GestureDetector I/flutter ( 6559): ? │ ← InkWell ← IconTheme ← DefaultTextStyle ← I/flutter ( 6559): ? │ AnimatedDefaultTextStyle ← ConstrainedBox ← MaterialButton ← I/flutter ( 6559): ? │ FlatButton ← Center ← DefaultTextStyle ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(88.0<=w<=411.4, h=36.0) I/flutter ( 6559): ? │ size: Size(98.0, 36.0) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderPointerListener relayoutBoundary=up3 I/flutter ( 6559): ? │ creator: Listener ← _GestureSemantics ← RawGestureDetector ← I/flutter ( 6559): ? │ GestureDetector ← InkWell ← IconTheme ← DefaultTextStyle ← I/flutter ( 6559): ? │ AnimatedDefaultTextStyle ← ConstrainedBox ← MaterialButton ← I/flutter ( 6559): ? │ FlatButton ← Center ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(88.0<=w<=411.4, h=36.0) I/flutter ( 6559): ? │ size: Size(98.0, 36.0) I/flutter ( 6559): ? │ behavior: opaque I/flutter ( 6559): ? │ listeners: down I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderPadding relayoutBoundary=up4 I/flutter ( 6559): ? │ creator: Padding ← Container ← Listener ← _GestureSemantics ← I/flutter ( 6559): ? │ RawGestureDetector ← GestureDetector ← InkWell ← IconTheme ← I/flutter ( 6559): ? │ DefaultTextStyle ← AnimatedDefaultTextStyle ← ConstrainedBox ← I/flutter ( 6559): ? │ MaterialButton ← ? I/flutter ( 6559): ? │ parentData: <none> I/flutter ( 6559): ? │ constraints: BoxConstraints(88.0<=w<=411.4, h=36.0) I/flutter ( 6559): ? │ size: Size(98.0, 36.0) I/flutter ( 6559): ? │ padding: EdgeInsets(16.0, 0.0, 16.0, 0.0) I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderPositionedBox relayoutBoundary=up5 I/flutter ( 6559): ? │ creator: Center ← Padding ← Container ← Listener ← I/flutter ( 6559): ? │ _GestureSemantics ← RawGestureDetector ← GestureDetector ← I/flutter ( 6559): ? │ InkWell ← IconTheme ← DefaultTextStyle ← I/flutter ( 6559): ? │ AnimatedDefaultTextStyle ← ConstrainedBox ← ? I/flutter ( 6559): ? │ parentData: offset=Offset(16.0, 0.0) I/flutter ( 6559): ? │ constraints: BoxConstraints(56.0<=w<=379.4, h=36.0) I/flutter ( 6559): ? │ size: Size(66.0, 36.0) I/flutter ( 6559): ? │ alignment: Alignment.center I/flutter ( 6559): ? │ widthFactor: 1.0 I/flutter ( 6559): ? │ heightFactor: expand I/flutter ( 6559): ? │ I/flutter ( 6559): ? └─child: RenderParagraph relayoutBoundary=up6 I/flutter ( 6559): ? │ creator: RichText ← Text ← Center ← Padding ← Container ← I/flutter ( 6559): ? │ Listener ← _GestureSemantics ← RawGestureDetector ← I/flutter ( 6559): ? │ GestureDetector ← InkWell ← IconTheme ← DefaultTextStyle ← ? I/flutter ( 6559): ? │ parentData: offset=Offset(0.0, 10.0) I/flutter ( 6559): ? │ constraints: BoxConstraints(0.0<=w<=379.4, 0.0<=h<=36.0) I/flutter ( 6559): ? │ size: Size(66.0, 16.0) I/flutter ( 6559): ? ╘═╦══ text ═══ I/flutter ( 6559): ? ║ TextSpan: I/flutter ( 6559): ? ║ inherit: false I/flutter ( 6559): ? ║ color: Color(0xdd000000) I/flutter ( 6559): ? ║ family: "Roboto" I/flutter ( 6559): ? ║ size: 14.0 I/flutter ( 6559): ? ║ weight: 500 I/flutter ( 6559): ? ║ baseline: alphabetic I/flutter ( 6559): ? ║ "Dump App" I/flutter ( 6559): ? ╚═══════════ I/flutter ( 6559): ? I/flutter ( 6559): └?no offstage children ``` 這是根`RenderObject`對象的`toStringDeep`函數的輸出。 當調試布局問題時,關鍵要看的是`size`和`constraints`字段。約束沿著樹向下傳遞,尺寸向上傳遞。 例如,在上面的轉儲中,您可以看到窗口大小,Size(411.4, 683.4),它用于強制[`RenderPositionedBox`](https://docs.flutter.io/flutter/rendering/RenderPositionedBox-class.html)下的所有渲染框到屏幕的大小, 約束條件為 BoxConstraints(w=411.4, h=683.4)。從`RenderPositionedBox`的轉儲中看到是由Center widget創建的(如creator字段所描述的), 設置其孩子的約束為:BoxConstraints(0.0<=w<=411.4,0.0<=h<=683.4)。一個子widget RenderPadding進一步插入這些約束以添加填充空間,padding值為EdgeInsets(16.0, 0.0, 16.0, 0.0),因此RenderConstrainedBox具有約束BoxConstraints(0.0<=w<=395.4, 0.0<=h<=667.4)。該creator字段告訴我們的這個對象可能是其[`FlatButton`](https://docs.flutter.io/flutter/material/FlatButton-class.html)定義的一部分,它在其內容上設置最小寬度為88像素,并且設置高度為36.0像素(這是Material Design設計規范中`FlatButton`類的尺寸標準)。 最內部RenderPositionedBox再次松開約束,這次是將按鈕中的文本居中。 在[`RenderParagraph`](https://docs.flutter.io/flutter/rendering/RenderParagraph-class.html)中基于它的內容來決定其大小。 如果您現在按照size鏈繼續往下查看,您會看到文本的大小是如何影響其按鈕的框的寬度的,它們都是根據孩子的尺寸自行調整大小。 另一種需要注意的是每個盒子描述的”relayoutSubtreeRoot”部分,它告訴你有多少祖先以某種方式依賴于這個元素的大小。 因此,`RenderParagraph`有一個`relayoutSubtreeRoot=up8`,這意味著當它`RenderParagraph`被標及為”dirty”時,它的八個祖先也必須被標記為”dirty”,因為它們可能受到新尺寸的影響。 如果您編寫自己的渲染對象,則可以通過覆蓋[`debugFillProperties()`](https://docs.flutter.io/flutter/rendering/Layer/debugFillProperties.html)將信息添加到轉儲。 將[DiagnosticsProperty](https://docs.flutter.io/flutter/foundation/DiagnosticsProperty-class.html)對象作為方法的參數,并調用父類方法。 ### 層 如果您嘗試調試合成問題,則可以使用[`debugDumpLayerTree()`](https://docs.flutter.io/flutter/rendering/debugDumpLayerTree.html)。對于上面的例子,它會輸出: ``` I/flutter : TransformLayer I/flutter : │ creator: [root] I/flutter : │ offset: Offset(0.0, 0.0) I/flutter : │ transform: I/flutter : │ [0] 3.5,0.0,0.0,0.0 I/flutter : │ [1] 0.0,3.5,0.0,0.0 I/flutter : │ [2] 0.0,0.0,1.0,0.0 I/flutter : │ [3] 0.0,0.0,0.0,1.0 I/flutter : │ I/flutter : ├─child 1: OffsetLayer 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 ← ? I/flutter : │ │ offset: Offset(0.0, 0.0) I/flutter : │ │ I/flutter : │ └─child 1: PictureLayer I/flutter : │ I/flutter : └─child 2: PictureLayer ``` 這是根`Layer`的`toStringDeep`輸出的。 根部的變換是應用設備像素比的變換; 在這種情況下,每個邏輯像素代表3.5個設備像素。 `RepaintBoundary` widget在渲染樹的層中創建了一個`RenderRepaintBoundary`。這用于減少需要重繪的需求量。 ### 語義 您還可以調用[`debugDumpSemanticsTree()`](https://docs.flutter.io/flutter/rendering/debugDumpSemanticsTree.html)獲取語義樹(呈現給系統可訪問性API的樹)的轉儲。 要使用此功能,必須首先啟用輔助功能,例如啟用系統輔助工具或`SemanticsDebugger` (下面討論)。 對于上面的例子,它會輸出: ``` I/flutter : SemanticsNode(0; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4)) I/flutter : ├SemanticsNode(1; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4)) I/flutter : │ └SemanticsNode(2; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4); canBeTapped) I/flutter : └SemanticsNode(3; Rect.fromLTRB(0.0, 0.0, 411.4, 683.4)) I/flutter : └SemanticsNode(4; Rect.fromLTRB(0.0, 0.0, 82.0, 36.0); canBeTapped; "Dump App") ``` ### 調度 要找出相對于幀的開始/結束事件發生的位置,可以切換[`debugPrintBeginFrameBanner`](https://docs.flutter.io/flutter/scheduler/debugPrintBeginFrameBanner.html)和[`debugPrintEndFrameBanner`](https://docs.flutter.io/flutter/scheduler/debugPrintEndFrameBanner.html)布爾值以將幀的開始和結束打印到控制臺。 例如: ``` I/flutter : ▄▄▄▄▄▄▄▄ Frame 12 30s 437.086ms ▄▄▄▄▄▄▄▄ I/flutter : Debug print: Am I performing this work more than once per frame? I/flutter : Debug print: Am I performing this work more than once per frame? I/flutter : ???????????????????????????????????????????????????? ``` [`debugPrintScheduleFrameStacks`](https://docs.flutter.io/flutter/scheduler/debugPrintScheduleFrameStacks.html)還可以用來打印導致當前幀被調度的調用堆棧。 ## 可視化調試 您也可以通過設置`debugPaintSizeEnabled`為`true`以可視方式調試布局問題。 這是來自`rendering`庫的布爾值。它可以在任何時候啟用,并在為true時影響繪制。 設置它的最簡單方法是在`void main()`的頂部設置。 當它被啟用時,所有的盒子都會得到一個明亮的深青色邊框,padding(來自widget如Padding)顯示為淺藍色,子widget周圍有一個深藍色框, 對齊方式(來自widget如Center和Align)顯示為黃色箭頭. 空白(如沒有任何子節點的Container)以灰色顯示。 [`debugPaintBaselinesEnabled`](https://docs.flutter.io/flutter/rendering/debugPaintBaselinesEnabled.html)做了類似的事情,但對于具有基線的對象,文字基線以綠色顯示,表意(ideographic)基線以橙色顯示。 [`debugPaintPointersEnabled`](https://docs.flutter.io/flutter/rendering/debugPaintPointersEnabled.html)標志打開一個特殊模式,任何正在點擊的對象都會以深青色突出顯示。 這可以幫助您確定某個對象是否以某種不正確的方式進行hit測試(Flutter檢測點擊的位置是否有能響應用戶操作的widget),例如,如果它實際上超出了其父項的范圍,首先不會考慮通過hit測試。 如果您嘗試調試合成圖層,例如以確定是否以及在何處添加`RepaintBoundary` widget,則可以使用[`debugPaintLayerBordersEnabled`](https://docs.flutter.io/flutter/rendering/debugPaintLayerBordersEnabled.html) 標志, 該標志用橙色或輪廓線標出每個層的邊界,或者使用[`debugRepaintRainbowEnabled`](https://docs.flutter.io/flutter/rendering/debugRepaintRainbowEnabled.html)標志, 只要他們重繪時,這會使該層被一組旋轉色所覆蓋。 所有這些標志只能在調試模式下工作。通常,Flutter框架中以“`debug...`” 開頭的任何內容都只能在調試模式下工作。 ## 調試動畫 調試動畫最簡單的方法是減慢它們的速度。為此,請將[`timeDilation`](https://docs.flutter.io/flutter/scheduler/timeDilation.html)變量(在scheduler庫中)設置為大于1.0的數字,例如50.0。 最好在應用程序啟動時只設置一次。如果您在運行中更改它,尤其是在動畫運行時將其值減小,則框架的觀察時可能會倒退,這可能會導致斷言并且通常會干擾您的工作。 ## 調試性能問題 要了解您的應用程序導致重新布局或重新繪制的原因,您可以分別設置[`debugPrintMarkNeedsLayoutStacks`](https://docs.flutter.io/flutter/rendering/debugPrintMarkNeedsLayoutStacks.html)和 [`debugPrintMarkNeedsPaintStacks`](https://docs.flutter.io/flutter/rendering/debugPrintMarkNeedsPaintStacks.html)標志。 每當渲染盒被要求重新布局和重新繪制時,這些都會將堆棧跟蹤記錄到控制臺。如果這種方法對您有用,您可以使用`services`庫中的`debugPrintStack()`方法按需打印堆棧痕跡。 ### 衡量應用啟動時間 要收集有關Flutter應用程序啟動所需時間的詳細信息,可以在運行`flutter run`時使用`trace-startup`和`profile`選項。 ``` $ flutter run --trace-startup --profile ``` 跟蹤輸出保存為`start_up_info.json`,在Flutter工程目錄在build目錄下。輸出列出了從應用程序啟動到這些跟蹤事件(以微秒捕獲)所用的時間: - 進入Flutter引擎時. - 展示應用第一幀時. - 初始化Flutter框架時. - 完成Flutter框架初始化時. 如 : ``` { "engineEnterTimestampMicros": 96025565262, "timeToFirstFrameMicros": 2171978, "timeToFrameworkInitMicros": 514585, "timeAfterFrameworkInitMicros": 1657393 } ``` ### 跟蹤Dart代碼性能 要執行自定義性能跟蹤和測量Dart任意代碼段的wall/CPU時間(類似于在Android上使用[systrace](https://developer.android.com/studio/profile/systrace.html))。 使用`dart:developer`的[Timeline](https://api.dartlang.org/stable/dart-developer/Timeline-class.html)工具來包含你想測試的代碼塊,例如: ``` Timeline.startSync('interesting function'); // iWonderHowLongThisTakes(); Timeline.finishSync(); ``` 然后打開你應用程序的Observatory timeline頁面,在”Recorded Streams”中選擇’Dart’復選框,并執行你想測量的功能。 刷新頁面將在Chrome的[跟蹤工具](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)中顯示應用按時間順序排列的timeline記錄。 請確保運行`flutter run`時帶有`--profile`標志,以確保運行時性能特征與您的最終產品差異最小。 ## Performance Overlay 要獲得應用程序性能圖,請將[`MaterialApp`](https://docs.flutter.io/flutter/material/MaterialApp/MaterialApp.html)構造函數的`showPerformanceOverlay`參數設置為true。 [`WidgetsApp`](https://docs.flutter.io/flutter/widgets/WidgetsApp-class.html)構造函數也有類似的參數(如果你沒有使用`MaterialApp`或者`WidgetsApp`,你可以通過將你的應用程序包裝在一個stack中, 并將一個widget放在通過[`new PerformanceOverlay.allEnabled()`](https://docs.flutter.io/flutter/widgets/PerformanceOverlay/PerformanceOverlay.allEnabled.html)創建的stack上來獲得相同的效果)。 這將顯示兩個圖表。第一個是GPU線程花費的時間,最后一個是CPU線程花費的時間。 圖中的白線以16ms增量沿縱軸顯示; 如果圖中超過這三條線之一,那么您的運行頻率低于60Hz。橫軸代表幀。 該圖僅在應用程序繪制時更新,因此如果它處于空閑狀態,該圖將停止移動。 這應該始終在發布模式(release mode)下測試,因為在調試模式下,故意犧牲性能來換取有助于開發調試的功能,如assert聲明,這些都是非常耗時的,因此結果將會產生誤導。 ## Material grid 在開發實現[Material Design](https://www.google.com/design/spec/material-design/introduction.html)的應用程序時, 將[Material Design基線網格](https://www.google.com/design/spec/layout/metrics-keylines.html)覆蓋在應用程序上可能有助于驗證對齊。 為此,[`MaterialApp` 構造函數](https://docs.flutter.io/flutter/material/MaterialApp/MaterialApp.html) 有一個`debugShowMaterialGrid`參數, 當在調試模式設置為true時,它將覆蓋這樣一個網格。 您也可以直接使用[`GridPaper`](https://docs.flutter.io/flutter/widgets/GridPaper-class.html)widget將這種網格覆蓋在非Material應用程序上 。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看