綜述
Flutter從架構上來講有3部分:linux
-
用Dart寫的Framework層,面向開發者 -
用Java/Kotlin寫的Embdder層(For Android,iOS是OC/Swift),純Flutter App不須要關心 -
用C++寫的Engine層,提供Dart運行環境和底層繪製能力
針對每一個部分,對應的源碼閱讀環境不一樣,調試方法也不一樣。android
對於閱讀環境,最重要的是可以正確地完成調用/定義的跳轉。git
對於調試環境,最重要的是可以設置斷點,單步執行。github
Framework環境配置
Framework的環境設置比較簡單。web
源碼閱讀
Framework的代碼在 https://github.com/flutter/flutter 下面,直接Clone下來。shell
親測安裝了Flutter插件的Android Studio是最好的閱讀工具,直接打開./packages/flutter
目錄,而後flutter pub get
便可。json
這一步可能報錯,主要是一些的版本衝突,按照信息解決便可。vim
源碼調試
經過Flutter Acttach
按鈕便可開始調試,可是若是要調試啓動部分的Dart代碼,用Debug
而不是Run
來啓動程序:windows
Embedder環境配置
Embedder的環境稍微複雜一點。微信
源碼閱讀
Embedder的代碼在engine的./shell/platform
下面:
tree -L 1
.
├── BUILD.gn
├── android
├── common
├── config.gni
├── darwin
├── embedder
├── fuchsia
├── glfw
├── linux
└── windows
用AS直接打開android
目錄便可,打開後會發現代碼都沒法解析對,這樣就無法跳轉了!!!
首先把根目錄設置爲Source
類型:
這時候只剩androidx
沒法解析了:
發現旁邊一個目錄已經聲明瞭依賴,因而按照提示,創建一個local.properties
文件,指出本地sdk路徑便可,而後執行Gradle命令,拉取更新:
後來查看文檔,發現其實另一個目錄已經有這些依賴了,直接在工程設置頁面添加一個classpath
便可:
../third_party/android_embedding_dependencies/
這個目錄是在engine外,buildroot下的,應該是以前gclient sync
的時候就解析build.gradle
拉下來的。
源碼調試
若是在打開Flutter的工程,打開Andorid的Activity是解析錯誤的:
須要以android做爲根目錄單獨打開,而後經過Run/Debug
按鈕再次啓動便可:
這裏單獨打開工程無需擔憂如何集成Flutter,gradle腳本已經搞定了。
Engine環境配置
Engine的配置是最複雜的。
源碼閱讀
把gn工具在src/out
目錄生成的compile_commands.json
文件移到src/flutter
目錄下,而後用CLion打開這個文件就能夠正確索引Engine的C++代碼了。
該文件是預編譯生成的索引,其餘編輯器也能夠支持,固然用CLion是最方便的。
源碼調試
官方提供了gdb的調試方法,可是沒有文檔,按照代碼註釋的文檔,也沒法運行成功,一直報下面的錯誤:
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site
看到網上有人已經在用lldb調試了,因而也按照這個思路成功了,
首先是把Android SDK的lldb-server
push到設備,創建一個信道,經過run-as
繞過權限問題:
# 注意換成本身的包名
adb push lldb-server /data/local/tmp/lldb-server
adb shell run-as com.example.flutter_demo \
cp -F /data/local/tmp/lldb-server /data/data/com.example.flutter_demo/lldb-server
adb shell run-as com.example.flutter_demo \
chmod a+x /data/data/com.example.flutter_demo/lldb-server
adb shell "run-as com.example.flutter_demo sh -c '/data/data/com.example.flutter_demo/lldb-server platform --server --listen unix-abstract:///data/data/com.example.flutter_demo/debug.socket'"
經過以上幾步已經創建能夠調試的通道了,而後啓動lldb,attach到指定進程(經過進程id),而後添加符號表:
adb shell pidof com.example.flutter_demo
lldb
(下面是lldb環境)
(lldb) platform select remote-android
(lldb) process attach -p 25382
(lldb) add-dsym ~/WorkProject/flutter_source_code/src/out/android_debug_unopt_arm64/libflutter.so
以前就注意到構建目錄下的這個so很是大,打包的so不過10M,這個接近300M,應該是存在大量調試信息。
這裏有兩個坑:
-
lldb進去以後,進程會掛起,必須用 c/continue
來恢復,否則沒法觸發邏輯,也就沒法觸發斷點 -
必須在 System.loadLibrary
以後才能添加符號表,不然失敗,若是仍是失敗,就把以上流程重試一遍~
如此,即可以開始調試了,下面演示在幀刷新位置設置斷點,而後觸發:
總結
以上即是Flutter源碼閱讀/調試環境的搭建,欲善其事,先利其器,後面就要開始真刀真槍擼源碼了。
參考
-
engine/flutter_gdb at master · flutter/engine -
Debugging the engine · flutter/flutter Wiki -
Debugging Flutter apps - Flutter -
Debugging Flutter apps programmatically - Flutter -
Using an OEM debugger - Flutter -
如何調試Android Native Framework -
Flutter Engine C++ 源碼調試初探 -
Android 調試橋 (adb) | Android 開發者 | Android Developers
本文分享自微信公衆號 - V大師在一號線(vimer2019)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。