前言
flutter tools中整合了很多強大的命令,比如:
- flutter create: 建立app、module、plugin、package
- flutter build: 構建apk、aar等
- flutter run: 執行 要想弄清楚各種命令背後的原理,一方面可以看靜態程式碼,另一方面則是動態除錯。
匯入flutter tools原始碼
我們知道flutter tools是用dart實現的,其原始碼位於path/to/flutter/packages/flutter_tools。 用Android Studio開啟該專案。
設定斷點
很多程式的除錯原理都類似,都是通過在啟動對應的程式時,傳入一些除錯相關的引數,讓對應的程式啟動後進行等待,等到Debugger程式attach到該程式後繼續執行。
Flutter Tools本質上是一個dart程式,它的除錯是Dart虛擬機器支援的。
具體到Android Studio上,有兩種配置方式:
- Dart Command Line App
- Dart Remote Debug
Dart Command Line App
這一種比較簡單,新建一個Dart Command Line App的Configuration。
Edit Configurations -》New -》 Dart Command Line App。如果所示:
![Flutter Tools的除錯](https://i.iter01.com/images/107bad32ffb5ef549038e170f2b202a0405d685eb5b53801b6ba50e433be0fd4.png)
Dart file指向flutter_tools.dart,這是入口檔案。 Programma arguments填上要執行的命令,比如 create flutter_app. 然後在其中的main方法上新增斷點,然後點選除錯按鈕,如圖所示
![Flutter Tools的除錯](https://i.iter01.com/images/c52e881aa1de77525b8312e62073498c1397ab65fd64575ee1d1d450065d5179.png)
![Flutter Tools的除錯](https://i.iter01.com/images/6af3096af6e662e0710c9f763288d1289b9305d205b1a9e4d6c6d68703f7333b.png)
Dart Remote Debug
新建一個Configuration。 Edit Configurations -》New -》 Dart Remote Debug -》 輸入Host為127.0.0.1,埠號為12345,如果所示:
![Flutter Tools的除錯](https://i.iter01.com/images/a7f23bae97852301f5861151fdc707060db866077e47ee2eec83c3767d50b70e.png)
--enable-vm-service:12345 --pause_isolates_on_start
來啟動dart虛擬機器。這兩個引數是告訴Dart虛擬機器開啟除錯埠12345,並在啟動後暫停等待。
我們可以通過設定FLUTTER_TOOL_ARGS
環境變數來設定引數
export FLUTTER_TOOL_ARGS="--enable-vm-service:12345 --pause_isolates_on_start"
複製程式碼
然後執行flutter命令
flutter create flutter_app
複製程式碼
此時會輸出如下資訊:
Observatory listening on http://127.0.0.1:12345/-7kH8m0Z5Ys=/
複製程式碼
同樣設好斷點,然後點選除錯按鈕,結果卻發現attach不上,錯誤資訊如圖所示
Failed to connect to the VM observatory service: java.io.IOException: Failed to connect: ws://127.0.0.1:12345/ws
Caused by: de.roderick.weberknecht.WebSocketException: error while creating socket to ws://127.0.0.1:12345/ws
Caused by: java.net.ConnectException: Connection refused (Connection refused)
複製程式碼
發現url對不上,Dart虛擬機器等待的url後面多了個-7kH8m0Z5Ys=
經過查資料,發現這是一種認證碼,是為了安全原因,防止應用被遠端除錯。可以通過引數--disable-service-auth-codes
進行關閉。
export FLUTTER_TOOL_ARGS="--enable-vm-service:12345 --pause_isolates_on_start --disable-service-auth-codes"
複製程式碼
然後重新執行flutter create flutter_app命令,這次成功了,如圖所示
![Flutter Tools的除錯](https://i.iter01.com/images/c01a642b29d26d9a9feed46099831c39e0eadc7bd12a23e08e1f02c3f4f98e5d.png)
除了通過FLUTTER_TOOL_ARGS環境變數,還可以直接執行dart命令。
dart --enable-vm-service:12345 --pause_isolates_on_start --disable-service-auth-codes /Users/szw/dev_tools/flutter/packages/flutter_tools/bin/flutter_tools.dart create flutter_app
複製程式碼
其實FLUTTER_TOOL_ARGS也是flutter命令傳給dart的。 flutter指令碼的路徑為flutter/bin/flutter,其中的最後一行就是
"$DART" --packages="$FLUTTER_TOOLS_DIR/.packages" $FLUTTER_TOOL_ARGS "$SNAPSHOT_PATH" "$@"
複製程式碼
總結
本文提到的方法不止適用於flutter tools,也適用於其他的dart應用。另外其他語言的除錯基本也都類似,大家可以舉一反三。