這個工具幫助你分析代碼,發現可能的錯誤。編程
終端進入flutter工程所在目錄,執行flutter analyze
json
dart語句級單步調試器和分析器api
終端進入flutter工程所在目錄,執行flutter run
命令運行app,運行的時候,在控制檯能夠看到一個Observatory URL(如http://127.0.0.1:8100/),咱們能夠經過瀏覽器打開,直接用語句級的單步調試程序鏈接到你的應用程序。瀏覽器
IDE內置調試器,運行的時候選擇debug按鈕intellij-idea
使用debugger()語句插入編程式斷點,調用這個方法須要import 'dart:developer'
。該debugger()語句帶有一個可選when參數,您能夠指定該參數僅在特定條件爲真時中斷,以下所示:app
void someFunction(double offset) { debugger(when: offset > 30.0); // ... }
咱們可使用flutter logs
來查閱日誌,這個命令基本上是對adb logcat
命令作了一層封裝。框架
若是打印日誌過多,Android的作法是設置日誌優先級或者有時會丟棄一些日誌行。爲了不這種狀況,咱們可使用debugPrint()
方法,這個方法是對print()
方法作了一層包裝,將輸出限制在一個級別,避免被Android內核丟棄。less
flutter框架中的許多類都有有用的toString
實現。按照慣例,這些輸出一般包括runtimeType
對象的一行,一般在ClassName
表格中。樹中使用的某些類也具備從那一點返回整個子樹的多行描述的toStringDeep
方法。有些詳細實現了toString
方法的類,有一個相應的只返回類型或者對對象只有一兩個詞語簡短描述的toStringShort
方法。ide
在開發過程當中,強烈建議您使用Flutter的「調試」模式,有時也稱爲「檢查」模式。若是你使用flutter run
命令,調試模式是默認的。在這種模式下,Dart assert語句被啓用,Flutter框架使用它來執行許多運行時檢查,驗證賦值是否合法。函數
當一個賦值不合法時,它會向控制檯報告,並提供一些上下文信息來幫助追蹤問題的根
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'), ), ), ); } }
源。
要關閉調試模式並使用發佈模式,請使用flutter run --release
運行您的應用程序,這也關閉了Observatory調試器。咱們也可用--profile
替代--release
, 一種關閉除了Observatory調試器以外的全部輔助工具的中間模式,也稱爲「分析模式」。
Flutter框架的每一層都提供了將其當前狀態轉儲到控制檯(使用debugPrint
)的功能。
咱們可使用debugDumpApp()轉儲Widgets庫的狀態,示例:
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'), ), ), ); } }
控制檯會輸出一個「扁平化」的樹,顯示了經過各類build函數建立的全部控件。
若是您嘗試調試佈局問題,那麼控件層的樹可能不夠詳細。在這種狀況下,您能夠經過調用debugDumpRenderTree()
轉儲渲染樹 。和debugDumpApp()
用法同樣,除了佈局或繪畫階段以外,您能夠隨時調用它。約定俗成,咱們最好在幀回調 或事件處理時調用它。
要調用debugDumpRenderTree()
,咱們須要import 'package:flutter/rendering.dart';
上面示例調用debugDumpRenderTree()
,輸出結果以下所示:
若是您嘗試調試佈局問題,那麼控件層的樹可能不夠詳細。在這種狀況下,您能夠經過調用debugDumpRenderTree()
轉儲渲染樹 。和debugDumpApp()
用法同樣,除了佈局或繪畫階段以外,您能夠隨時調用它。約定俗成,咱們最好在幀回調 或事件處理時調用它。
要調用debugDumpRenderTree()
,咱們須要import 'package:flutter/rendering.dart';
上面示例調用debugDumpRenderTree()
,輸出結果以下所示:
若是您正在嘗試調試混合問題,則可使用 debugDumpLayerTree()
。對於上面的例子,它會輸出:
這是在根圖層對象上調用toStringDeep
的輸出。
根的變換是應用設備像素比的變換;在本例中,每一個邏輯像素的比率爲3.5個設備像素。
RepaintBoundary
控件在渲染層中建立了一個新的圖層RenderRepaintBoundary
,一般用來減小須要從新繪製的層數。
您還可使用debugDumpSemanticsTree()
得到語義樹(該樹存在於系統可訪問的api中)的轉儲。要使用這個功能,您必須首先設置容許訪問,例如,經過啓用系統可訪問性工具或SemanticsDebugger
。
上面的例子調用debugDumpSemanticsTree()
,控制檯將會輸出下面結果:
https://img-blog.csdn.net/20171227193605109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvam9obldjaGV1bmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
你還能夠經過設置debugPaintSizeEnabled
爲true來更直觀的調試佈局問題,這是渲染庫中的一個布爾變量,當該變量爲true時,它能夠隨時生效,而且影響全部地方的繪製。最簡單的辦法是在void main()
主函數頂部入口去設置它。
當咱們打開可視化調試時,全部子控件內邊距會有一個明亮漸變的深藍色邊框,控件中間顯示一個黃色箭頭,控件間距會顯示灰色。
debugPaintBaselinesEnabled
的功能相似於對象的基準線,字母基線顯示亮綠色,表意基線顯示橙色。
debugPaintPointersEnabled
標誌位會打開一種特殊模式,讓全部的對象都突出顯示,這個能夠幫助你發現哪個對象不能正確的進行測試,好比,某個對象在其父類的範圍以外,就不會第一時間被考慮進行命中測試。
若是您嘗試調試混合圖層,例如,肯定是否以及在何處添加RepaintBoundary
控件,可使用debugPaintLayerBordersEnabled
標誌位,它使用橙色來繪製每一個圖層的邊界,或者用debugRepaintRainbowEnabled
標誌位,當圖層從新繪製時,它將讓圖層顯示旋轉的色彩。
全部這些標誌位只在調試模式下工做。通常來講,在Flutter框架中,任何以「debug…」開頭的變量或方法,都只能在調試模式下有效。
調試動畫最簡單的方法是減慢它們的速度。爲此,將timeDilation
變量(在scheduler
庫中)設置爲大於1.0的數字,例如50.0。最好在應用程序啓動時只設置一次。若是您在運行中更改它,尤爲是在動畫運行時將其值變小,則框架可能會觀察到時間倒退,這可能會致使斷言,而且一般會影響效果。
要知道致使你應用程序從新佈局或從新繪製的緣由,您能夠分別設置 debugPrintMarkNeedsLayoutStacks
和 debugPrintMarkNeedsPaintStacks
標誌。
每當渲染框被要求從新佈局和從新繪製時,都會隨時將堆棧跟蹤日誌打印到控制檯。若是這種方法對你有用,你可使用service
s庫中的debugPrintStack()
方法按需打印本身的堆棧跟蹤日誌。
要收集有關Flutter應用程序啓動所需時間的詳細信息,能夠執行以下命令:
$ flutter run --trace-startup --profile
跟蹤日誌被保存在你的Flutter工程build目錄下一個叫start_up_info.json
的json文件裏。日誌會列出從應用啓動到這些以微秒捕獲的跟蹤事件所用的時間:
進入Flutter引擎代碼的時間
繪製應用第一幀的時間
初始化Flutter框架的時間
完成Flutter框架初始化的時間
例如:
{ "engineEnterTimestampMicros": 96025565262, "timeToFirstFrameMicros": 2171978, "timeToFrameworkInitMicros": 514585, "timeAfterFrameworkInitMicros": 1657393 }
要執行自定義性能跟蹤,去測量dart任一代碼塊的
CPU時間和牆上時鐘時間,實現相似Android性能分析工具systrace
的功能,咱們可使用dart:developer
裏面的時間軸工具來包裝你想測試的代碼:
Timeline.startSync('interesting function'); // iWonderHowLongThisTakes(); Timeline.finishSync();
而後打開應用分析器的時間軸頁面,檢查dart記錄選項並執行你想測試的功能。
刷新該頁面,將會在Chrome瀏覽器的跟蹤工具中按時間順序顯示應用程序的時間軸記錄。
務必使用flutter run --profile
命令運行應用程序,以保證運行時性能特徵與最終產品的性能緊密匹配。
要得到應用程序性能的圖形視圖, 咱們須要將MaterialApp
構造函數的showPerformanceOverlay
參數設爲true, WidgetsApp
構造函數也有相似的參數。 若是你沒有使用MaterialApp
或者WidgetsApp
, 你能夠將你的應用程序封裝在一個堆棧中,調用new PerformanceOverlay.allEnabled()
方法建立一個控件放在堆棧上。
這將顯示兩個圖表:上面是GPU線程花費的時間,下面是CPU線程花費的時間。圖中的白線沿垂直軸顯示16ms的增量;若是圖表通過其中的一條白線,那麼你運行速度在60Hz如下,橫軸表明框架。圖表只會在應用程序繪製時更新,因此若是處於空閒狀態,圖表將中止移動。
這個操做必定是在發佈模式下完成,由於在調試模式下,會故意犧牲性能來換取旨在輔助開發的昂貴的斷言,這樣結果將是誤導性的。
當咱們開發實現Material design
的應用時,應用上會覆蓋一個幫助驗證對齊的Material Design
基線網格。 爲此,在調試模式下,將MaterialApp
構造函數的debugShowGrid
參數設爲true,將會覆蓋這樣一個網格。
你也能夠直接使用GridPaper
控件在非Material
應用程序上覆蓋這樣的網格。