as工程放到源码编译_Flutter源码剖析(二):源码的阅读与调试环境配置

综述

Flutter从架构上来说有3部分:

  • 用Dart写的Framework层,面向开发者
  • 用Java/Kotlin写的Embdder层(For Android,iOS是OC/Swift),纯Flutter App不需要关心
  • 用C++写的Engine层,提供Dart运行环境和底层绘制能力

针对每个部分,对应的源码阅读环境不同,调试方法也不同。

对于阅读环境,最重要的是能够正确地完成调用/定义的跳转

对于调试环境,最重要的是能够设置断点,单步执行

Framework环境配置

Framework的环境设置比较简单。

源码阅读

Framework的代码在 https://github.com/flutter/flutter 下面,直接Clone下来。

亲测安装了Flutter插件的Android Studio是最好的阅读工具,直接打开./packages/flutter 目录,然后flutter pub get即可。

这一步可能报错,主要是一些的版本冲突,按照信息解决即可。

源码调试

通过Flutter Acttach按钮即可开始调试,但是如果要调试启动部分的Dart代码,用Debug而不是Run来启动程序:

3be7fe8bf36faa0fbf8ece162f8d51f6.png

Embedder环境配置

Embedder的环境稍微复杂一点。

源码阅读

Embedder的代码在engine的./shell/platform下面:

tree -L 1
.
├── BUILD.gn
├── android
├── common
├── config.gni
├── darwin
├── embedder
├── fuchsia
├── glfw
├── linux
└── windows
540b6a792e07ca933cf6ccc3581d2783.png

用AS直接打开android目录即可,打开后会发现代码都无法解析对,这样就没法跳转了!!!

首先把根目录设置为Source类型:

e71dec61aac8376d03df7beecb654a02.png

这时候只剩androidx无法解析了:

2bb94587607da58066c7eb53427ee65c.png

发现旁边一个目录已经声明了依赖,于是按照提示,建立一个local.properties文件,指出本地sdk路径即可,然后执行Gradle命令,拉取更新:

a8b7708ebca922680c0a98b0f831f719.png

后来查看文档,发现其实另外一个目录已经有这些依赖了,直接在工程设置页面添加一个classpath即可:

../third_party/android_embedding_dependencies/

这个目录是在engine外,buildroot下的,应该是之前gclient sync的时候就解析build.gradle拉下来的。

源码调试

如果在打开Flutter的工程,打开Andorid的Activity是解析错误的:

37d9e35970a9476985c97f595656b1f7.png

需要以android作为根目录单独打开,然后通过Run/Debug按钮再次启动即可:

1b7e2491aa8d915f4973007a5b12e444.png

这里单独打开工程无需担心如何集成Flutter,gradle脚本已经搞定了。

Engine环境配置

Engine的配置是最复杂的。

源码阅读

把gn工具在src/out 目录生成的compile_commands.json文件移到src/flutter目录下,然后用CLion打开这个文件就可以正确索引Engine的C++代码了。

0554238994eb228b6bd99157d909b477.png

该文件是预编译生成的索引,其他编辑器也可以支持,当然用CLion是最方便的。

源码调试

官方提供了gdb的调试方法,但是没有文档,按照代码注释的文档,也无法运行成功,一直报下面的错误:

Could not find platform independent libraries 
Could not find platform dependent libraries 
Consider setting $PYTHONHOME to [:]
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,应该是存在大量调试信息。

8cc93125cf1c3109a16fbef45fed00c8.png

这里有两个坑:

  1. lldb进去之后,进程会挂起,必须用c/continue来恢复,不然无法触发逻辑,也就无法触发断点
  2. 必须在System.loadLibrary之后才能添加符号表,否则失败,如果还是失败,就把以上流程重试一遍~

如此,便可以开始调试了,下面演示在帧刷新位置设置断点,然后触发:

2507f113307a5a612addf9c6c6adbd8b.png

总结

以上便是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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

万州哪里有维修服务器,网关可以设在服务器、微机或大型机上

网关可以设在服务器、微机或大型机上。由于网关具有强大的功能并且大多数时候都和应用有关,它们比路由器的价格要贵一些。另外,由于网关的传输更复杂,它们传输数据的速度要比网桥或路由器低一些。正是由于网关较慢,它们有造成网络…

workbook加载文件路径_【Python】文件重命名(按照Excel清单)

问题:1、扫描了很多文件,想批量加上文件编号2、网页下载了一堆图片,批量加上图片分类3、文件命名不规范,想批量调整效果图:需求解析:1、想重命名,就要有原名字和修改后的名字,清单准…

ppap文件过程流程图制作_收藏 | 据说PPAP的精华都在这个PPT里!一起来鉴定下

一组数字的PPAP3种情况必须提交8种情况通知提交5种提交等级3种提交状态18份提交内容“3”——以下3种情况,必须向顾客提交PPAP:1)一种新的零件或产品;2)对以前所提供不符合零件的纠正;3)由于设计记录、规范或材料方面的工程变更从…

++实现 ipv6数据报_IPV6报文格式和IPV4有什么区别?

前言RFC2460定义了IPv6数据报格式。总体结构上,IPv6数据报格式与IPv4数据报格式是一样的,也是由IP报头和数据(在IPv6中称为有效载荷)这两个部分组成的。但在IPv6数据报数据部分还可以包括0个或者多个IPv6扩展报头(Extension header)。正文1IPV6报文格式如…

曲面设计步骤pdf_3dmax模渲大师|室外设计师怎么用3dmax疯狂模渲大师制作室内设计效果图的外景天空?...

3dmax模渲大师|室外设计师怎么用3dmax疯狂模渲大师制作室内设计效果图的外景天空?这次食住玩讲的是第十三章的第1节,3dmax疯狂模渲大师室外设计篇的第1课——“外景天空”的使用方法。在室内设计效果图领域,也有要涉及室外的时候。…

go 修改结构体方法_Go36-13-结构体及其方法

结构体及其方法结构体类型表示的是实实在在的数据结构。一个结构体类型可以包含若干个字段,每个字段通常都需要有确切的名字和类型。结构体类型也可以不包含任何字段,这样并不是没有意义的,因为我们还可以为这些类型关联上一些方法&#xff0…

iphone日历显示周视图_用敬业签记录放假安排 2021年放假安排日历

2021年已经踏着轻快的步伐向我们一路小跑而来,新的一年中,除了可以做更多的成绩之外,还有很多假期伴随而来。做好放假安排就可以让假期更加充实,为了能够更好的记录放假安排和相关事项可用敬业签这款便签软件。使用敬业签记录放假…

oracle删除orcl库_oracle删除数据文件

在我们详细介绍之前,我们必须说清楚一点:Oracle不提供如删除表、视图一样删除数据文件的方法,数据文件是表空间的一部分,所以不能“移走”表空间。一、使用offline数据文件的方法非归档模式使用:alter database datafi…

datagridview取消默认选中_winform datagridview中的 combobox如何选中默认值?

看了半天,我终于知道你是在添加行,并不是绑定——你是试图从数据库中逐行读取数据,然后赋值到Combobox中,对不?请不要这样做!请直接把DataTable作为数据源赋值给GridView!public partial class …

人工智能的炒作_为什么人工智能被过度炒作?

像任何新技术一样,人工智能也经历了称为“炒作周期”的各个阶段。它们从技术触发器开始。如果超过了人们设定的期望值(过度夸大),那么就会带来技术未达到预期的幻灭感,然后就是带来启发的成功案例,最后是生产力的稳定期。有了人工…

opencv轮廓周长原理_opencv轮廓逼近的精度参数与周长cvContourPerimeter的汇总

1)CV_Assert():若括号中的表达式值为false,则返回一个错误信息。函数原型是:#define CV_Assert( expr ) if((expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) )2)cvContourPerimeter&#x…

Eclipse 导入项目乱码问题

Eclipse 导入项目乱码问题 1.编码不对 a.对某文件或某工程更改编码: 鼠标移到工程名或文件名,右键->Properties->Resource->Text file enCoding ->更改编码(GBK、UTF-8等)->Apply->OK退出 b.修改整个命名空…

mysql的所有聚合函数_MySQL 聚合函数(一)聚合(组合)函数概述

MySQL版本:5.7+ 一、MySQL 5.7中的聚合函数 MySQL 5.7中的聚合函数如下: 除非另有说明,否则组合函数会忽略NULL值。 如果在不包含Group By子句的语句中使用组合函数,就等效于对所有行进行分组。(个人理解是,结果总是只有一行。)关于这点的更多信息,后面的小节“MySQL处理…

mysql中的comment用法

mysql中的comment用法 在MySQL数据库中,字段或列的注释是用属性comment来添加。 创建新表的脚本中, 可在字段定义脚本中添加comment属性来添加注释。 示例代码如下: create table test( id int not null default 0 comment ‘用户id’ ) 如…

docker 安装mysql_Docker安装MySQL完整版流程

我们自己在linux上安装mysql的话,超级麻烦,安装完后还要进行各种各样的配置,之前在docker专题写了用docker安装mysql的快速版本以及修改编码的方式,这里总结一下安装流程和命令。环境Linux version 3.10.0-693.2.2.el7.x86_64dock…

mysql 转型_MySQL的未来在哪?

阿里云 MySQL&MariaDB 数据库产品结合开源社区,提供了稳定、可靠、便捷、弹性的在线数据库服务,帮助全球企业客户进行数字化转型。MySQL发展经历了一系列变化,从Sun到Oracle,发展也经过了几个阶段。MySQL从5.7版本开始走上了代…

mongoose换成mysql_如何将MongoDB数据库的数据迁移到MySQL数据库中

FAQ v2.0终于上线了,断断续续忙了有2个多月。这个项目是我实践的第一个全栈的项目,从需求(后期有产品经理介入)到架构,再到设计(有征询设计师的意见)、构建(前端、后台、数据库、服务器部署),也是第一次独立负责一个项目&#xff…

java虚拟机——JVM

JVM:java虚拟机,简称JVM,是运行所有java程序的假想计算机,是java程序的运行环境,是java最具吸引力的特征之一。我们编写的java代码,都运行在JVM之上。 跨平台:任何软件的运行,都必须…

mysql 5.0.37.tar.gz_Linux下MySQL5.0.37安装配置步骤

Linux下安装MySQL5.0.37需要以下面三个包:MySQL-client-community-5.0.37-0.rhel3.i386.rpmMySQL-server-community-5.0.37-0.rhel3.i386.rpmperl-DBI-1.53-2.fc7.i386.rpm(以下步骤需要root权限)1.验证是否已经安装过MySQLrpm -qa|grep MySQL如果发现有安装过,并需要卸载,使用…

JRE和JDK

JRE:是java程序的运行时环境,包含JVM和运行时所需要的核心类库。 JDK:时java程序开发工具包,包含JRE和开发人员使用的工具。 我们想要运行一个已有的java程序,那么只需要安装JRE即可。 我们想要开发一个全新的java程序…