2.1 Flutter源码调试

一般情况下,通过flutter run 构建并运行flutter工程时,会生成Engine/Embedder的依赖配置并通过Gradle从云端仓库下载官方已经构建好病上传的构建产物,但是我们也可以自定义参数指定使用本地自己构建的Engine/Embedder产物。Flutter 编译Engine/Embedder见:Flutter源码获取与编译

基于本地构建产物编译Flutter应用

$ ../flutter/bin/flutter run --local-engine-src-path ~/flutter_source/src --local-engine=android_debug_unopt     #使用自己的目录

Flutter Framework层调试

Framework层调试,Android Studio本身就是支持的,就不做赘述了。

Flutter Embedder层调试

  通过上述的指令(--local-engine-src-path,--local-engine)参数指定自定义的Engine和Embeder构建一个Flutter App,并不能在Android Studio中像Framework那样调试Embedder的Java代码,因为当前项目呗识别为Flutter工程,而非Android工程。如果使用Android Studio直接打开flutter工程下的android目录,则相关的Local Engine参数都没有配置,自然无法被当作源码解析。
  对于Embedder的调试,也是可以通过Android项目构建时候增加相关参数,指定使用自己编译后的文件,在src/out/android_debug_unopt中有Embedder的jar文件和pom文件,可以构建自己的本地仓库,代替默认的远程仓库。
  但是也可以通过更简单的方式来调试

使用Android Studio 对Embedder源码调试

无论是使用VS Code还是Android Studio都需要上述LLDB的配置准备工作,推荐使用上面的VS Code,因为使用Android Studio的这种方式调试的时候使用的是Engine变异产物的flutter.jar文件
步骤:

  1. 创建一个Flutter Module工程,命令行创建
../flutter/bin/flutter create -t module flutter_module
  1. 将上述flutter module打包成aar
../flutter/bin/flutter build aar
  1. 创建一个常规的Android 工程,将Enfine源码构建出来的flutter.jar文件和上面打包的aar文件复制到libs目录
  2. 配置app/build.gradle
android {
 defaultConfig {
        ndk { // 确保加入目标架构的libflutter.so进行构建
            abiFilters "armeabi-v7a" 
        }
    }

 compileOptions { // Embedder须使用JDK1.8构建
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

dependencies {
    implementation files('libs/flutter.jar') // Engine和Embedder源码
    implementation files('libs/flutter_debug-1.0.aar') // Framework的构建产物
}

Engine源码调试

  对于Engine的调试相对来说就会复杂一些,简单说明下,调试时候,源码在PC端,而代码运行在具体设备(Android/IOS等),那么挑食过程必然有数据通信和通信协议,比如Java代码调试常见的Socket和JDWP,而Engine是基于C++开发,很多步骤要手动完成。此外会准备一个Flutter项目方便后续调试,下面提到的com.lwj.flutter_app是一个Flutter的默认计数器demo项目。

  • LLDB调试配置
    首先调试器选lldb,简单说明下lldb,Android端调试Native代码一般也使用lldb,在Android Studio SDK Manager界面可以安装lldb(注意: 低版本的Android Studio 可能找不到该选项,高版本的Android studio也有可能找不到该选项,高版本找不到是因为lldb相当于内置了,不需要单独安装,但是不方便外部调用(手动下载戳 LLDB),Android Studio的安装目录和Flutter Engine编译产物的文件夹下都有lldb-server文件,不必纠结Android studio版本和是否可以独立下载 )
    lldb示意图

关于lldb远程调试的配置方式参考:LLDB Remote Debugging
(PS:按照上面文档配置后存在一个问题,就是最后挂载进程时,无法关联到我们的flutter应用进程。这个是因为系统权限限制,除非将手机ROOT,否则一直会提示attach fail
那这个问题怎么解决?其实可以将lldb-server添加到需要调试的应用中。通过run-as获取应用权限,进入应用目录下进行操作。注意,使用run-as的应用只能是debug应用,其他应用不可以使用。)

LLDB配置步骤大致如下:

  1. 确定lldb-文件位置(可手动下载 LLDB,)
# Android studio安装目录下的路径(不确定从那个版本开始内置)
/Applications/Android\ Studio.app/Contents/plugins/android-ndk/resources/lldb/android/armeabi/lldb-server 
# Flutter Engine目录下的lldb-server路径
/Users/lwj/Desktop/flutter_source/engine/src/third_party/android_tools/ndk/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/11.0.5/lib/linux/arm/lldb-server
  1. 找到lldb-server所在目录位置,并将其推送到手机中
    我用的是Flutter Engine 编译产物目录下的lldb-server,执行adb命令,将lldb-server push到临时文件夹
adb push /Users/lwj/Desktop/flutter_source/engine/src/third_party/android_tools/ndk/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/11.0.5/lib/linux/arm/lldb-server /data/local/tmp/lldb-server
  1. 将lldb-server复制到app的私有目录
    执行命令如下:
adb shell run-as com.lwj.flutter_app cp -F /data/local/tmp/lldb-server /data/data/com.lwj.flutter_app/lldb-server
  1. 赋予lldb-server可执行权限
adb shell run-as com.lwj.flutter_app \chmod a+x /data/data/com.lwj.flutter_app/lldb-server
  1. 启动lldb-server,这样设备就可以接受相应调试命令了
adb shell "run-as com.lwj.flutter_app sh -c '/data/data/com.lwj.flutter_app/lldb-server platform --server --listen unix-abstract:///data/data/com.lwj.flutter_app/debug.socket'"
  1. 获取待调试应用进程id
    先使用自己编译的Flutter Engine启动demo工程
    在demo目录下执行命令
flutter run --local-engine-src-path=/Users/lwj/Desktop/flutter_source/engine/src --local-engine=/Users/lwj/Desktop/flutter_source/engine/src/out/android_debug_unopt

执行命令获取pid

adb shell pidof com.lwj.flutter_app
30226

到这里LLDB的配置就完成了,我们可以基于上面的配置,通过VS Code断点调试Flutter Engine源码

使用VS Code源码调试

  1. 使用VS Code打开Engine所在目录
  2. 配置 launch.json文件
{
    "version": "0.2.0",
    "configurations": [
    {
      "type": "lldb",
      "request": "attach",
      "name": "android_attach",
      "pid": "30226",  # 上面获取的pid
      "initCommands": [
        "platform select remote-android",
        "platform connect unix-abstract-connect:///data/data/com.lwj.flutter_app/debug.socket"
      ],
      "postRunCommands": [
        "add-dsym /Users/lwj/Desktop/flutter_source/engine/src/out/android_debug_unopt/libflutter.so",
        "settings set target.source-map /Users/lwj/Desktop/flutter_source/engine/src/out/android_debug_unopt /Users/lwj/Desktop/flutter_source/engine/src/"
      ]
    }
    ]
  }
  1. 设置断点,F5开始调试。
    我将断点打到了 src/flutter/lib/ui/window/window.cc
    点击demo的+号,触发断点
    断点

参考:
《Flutter内核源码剖析》
Flutter Engine源码调试

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容