前言
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。如果所示:
Dart file指向flutter_tools.dart,這是入口檔案。 Programma arguments填上要執行的命令,比如 create flutter_app. 然後在其中的main方法上新增斷點,然後點選除錯按鈕,如圖所示
接下來程式會在斷點處停下來,如圖所示 可以看到args正是我們設定的引數。Dart Remote Debug
新建一個Configuration。 Edit Configurations -》New -》 Dart Remote Debug -》 輸入Host為127.0.0.1,埠號為12345,如果所示:
IDE中提示我們使用--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_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應用。另外其他語言的除錯基本也都類似,大家可以舉一反三。