程序調試是程序投入運行以前,使用手工或編譯程序等方法進行的測試,主要用以修正語法錯誤和邏輯錯誤。程序調試是保證計算機信息系統正確性的必不可少的步驟。
在Flutter應用開發中,Android Studio和VSCode是兩種比較常見的集成開發環境,所以項目調試也圍繞這兩款IDE進行。Android Studio爲Flutter提供完整的集成IDE體驗,所以Android的調試技巧對於Flutter來講也是適用的。在 Flutter 中,調試代碼主要分爲輸出日誌、斷點調試和佈局調試 3 類,所以Flutter的調試也將圍繞這 3 個主題。瀏覽器
爲了便於跟蹤和記錄應用的運行狀況,咱們在開發時一般會在一些關鍵步驟輸出日誌(Log),在Flutter中咱們使用 print 函數在控制檯打印出相關的上下文信息。經過這些信息,就能夠定位代碼中可能出現的問題。不過,因爲涉及 I/O 操做,使用 print 來打印信息會消耗較多的系統資源。同時,這些輸出數據極可能會暴露 App 的執行細節,因此咱們在發佈正式版時還須要屏蔽掉這些輸出。async
不過最工程化的作法是讀取項目配置文件,根據運行環境來開啓日誌調試功能。爲了根據不一樣的運行環境來開啓日誌調試功能,咱們可使用 Flutter 提供的debugPrint 來代替 print。debugPrint 函數一樣會將消息打印至控制檯,但與 print 不一樣的是,它提供了定製打印的能力。也就是說,咱們能夠向 debugPrint 函數,賦值一個函數聲明來自定義打印行爲。函數
好比在下面的代碼中,咱們將 debugPrint 函數定義爲一個空函數體,這樣就能夠實現一鍵取消打印的功能了。工具
debugPrint = (String message, {int wrapWidth}) {};//空實現
在 Flutter 中,咱們可使用不一樣的 main 文件來表示不一樣環境下的入口。一樣,在Flutter開發中,能夠經過 main.dart 與 main-dev.dart,去分別定義生產環境與開發環境不一樣的打印日誌行爲。佈局
在下面的例子中,咱們將生產環境的 debugPrint 定義爲空實現,將開發環境的 debugPrint 定義爲同步打印數據,以下所示。開發工具
//main.dart void main() { // 將debugPrint指定爲空的執行體, 因此它什麼也不作 debugPrint = (String message, {int wrapWidth}) {}; runApp(MyApp()); } //main-dev.dart void main() async { // 將debugPrint指定爲同步打印數據 debugPrint = (String message, {int wrapWidth}) => debugPrintSynchronously(message, wrapWidth: wrapWidth); runApp(MyApp()); }
能夠看到,在代碼實現上,咱們只要將應用內全部的 print 都替換成 debugPrint,就能夠知足開發環境下打日誌的需求,也能夠保證生產環境下應用的執行信息不會被意外打印。測試
輸出日誌當然方便,但若是要想獲取更爲詳細,或是粒度更細的上下文信息,靜態調試的方式很是不方便。這時,咱們須要更爲靈活的動態調試方法,即斷點調試。斷點調試可讓代碼在目標語句上暫停,讓程序逐條執行後續的代碼語句,來幫助咱們實時關注代碼執行上下文中全部變量值的詳細變化過程。優化
Android Studio 提供了斷點調試的功能,調試 Flutter 應用與調試原生 Android 代碼的方法徹底同樣,具體能夠分爲三步,即標記斷點、調試應用、查看信息。spa
下面以 Flutter 默認的計數器應用模板爲例,觀察代碼中 _counter 值的變化,體會斷點調試的全過程。debug
首先是標記斷點。既然咱們要觀察 _counter 值的變化,所以在界面上展現最新的 _counter 值時添加斷點,去觀察其數值變化是最理想的。所以,咱們在行號右側點擊鼠標,能夠把斷點加載到初始化 Text 控件所示的位置。
在下圖的例子中,咱們爲了觀察 _counter 在等於 20 的時候是否正常,還特地設置了一個條件斷點 _counter==20,這樣調試器就只會在第 20 次點擊計數器按鈕時暫停下來。
添加斷點後,對應的行號將會出現圓形的斷點標記,並高亮顯示整行代碼。到此,斷點就添加好了。固然,咱們還能夠同時添加多個斷點,以便更好地觀察代碼的執行過程。
接下來則是調試應用了。和以前經過點擊Run 按鈕的運行方式不一樣,這一次咱們須要點擊工具欄上的蟲子圖標,以調試模式啓動 App,以下圖所示。
等調試器初始化好後,咱們的程序就啓動了。因爲設置了斷點,因此當代碼運行到了斷點位置,自動進入了 Debug 視圖模式,以下圖所示。
按照功能的不一樣,能夠把 Debug 視圖模式劃分爲 4 個區域,即 A 區控制調試工具、B 區步進調試工具、C 區幀調試窗口、D 區變量查看窗口。
控制調試工具區域主要用來控制調試的執行狀況,以下圖所示。
咱們能夠點擊繼續執行按鈕來讓程序繼續運行、點擊終止執行按鈕來讓程序終止運行、點擊從新執行按鈕來讓程序從新啓動,或是在程序正常執行時,點擊暫停執行按鈕按鈕來讓程序暫停運行。固然,咱們能夠點擊編輯斷點按鈕來編輯斷點信息,或是點擊禁用斷點按鈕來取消斷點。
步進調試工具區域主要用來控制斷點的步進狀況,以下圖所示。
能夠點擊單步跳過按鈕來讓程序單步執行(但不會進入方法體內部)、點擊單步進入或強制單步進入按鈕讓程序逐條語句執行,甚至還能夠點擊運行到光標處按鈕讓程序執行到在光標處。認爲斷點所在的方法體已經無需執行時,則能夠點擊單步跳出按鈕讓程序馬上執行完當前進入的方法,從而返回方法調用處的下一行。擔任,還能夠點擊表達式計算按鈕來經過賦值或表達式方式修改任意變量的值。
C 區用來指示當前斷點所包含的函數執行堆棧,D 區則是其堆棧中的函數幀所對應的變量。
除了輸出日誌、斷點調試,佈局分析也是開發中不可缺乏的代碼優化手段。藉助Flutter提供的Flutter Inspector 可視化工具,能夠幫助咱們診斷佈局問題。打開Android Studio,而後點擊工具欄上的「Open DevTools」按鈕便可啓動 Flutter Inspector,以下圖所示。
隨後,Android Studio 會打開瀏覽器,將Flutter應用程序的的 Widget 樹結構展現在面板中。能夠看到,Flutter Inspector 所展現的 Widget 樹結構,與代碼中實現的 Widget 層次是一一對應的。
除了進行佈局調試外,還可使用Flutter Inspector進行佈局調優。
除了Android Studio外,VSCode也是一款比較常見的Flutter應用程序開發工具。使用VSCode提供的圖形化調試界面,開發者能夠很方便的進行Flutter應用的調試工做。使用VSCode打開Flutter項目,而後點擊VSCode的斷點調試按鈕便可開啓調試,以下圖所示。須要說明的是,第一次使用VSCode進行斷點調試時,須要先安裝並激活Dart DevTools調試工具。若是不肯定是否綁定過DevTools工具,可使用快捷鍵【command+shift+p】打開VSCode工具欄,而後輸入Open DevTools打開調試窗口。而後,在須要調試的代碼處設置斷點,點擊左上方的開啓調試按鈕開啓調試便可。當代碼運行到斷點處時,就會停留在斷點處,而後就能夠進行相關調試操做。