Flutter源碼剖析(二):源碼的閱讀與調試環境配置

綜述

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,應該是存在大量調試信息。

這裏有兩個坑:

  1. lldb進去以後,進程會掛起,必須用 c/continue來恢復,否則沒法觸發邏輯,也就沒法觸發斷點
  2. 必須在 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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索