综述
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源创计划”,欢迎正在阅读的你也加入,一块儿分享。