<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Gityuan</title>
    <description>袁辉辉, Gityuan, Android博客, Android源码, Flutter博客，Flutter源码</description>
    <link>http://gityuan.com/</link>
    <atom:link href="http://gityuan.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Mon, 18 Oct 2021 12:02:49 +0000</pubDate>
    <lastBuildDate>Mon, 18 Oct 2021 12:02:49 +0000</lastBuildDate>
    <generator>Jekyll v3.9.0</generator>
    
      <item>
        <title>字节跳动为什么选用Flutter：并非跨平台终极之选，但它可能是不一样的未来</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;2018 年 12 月 ，Google  宣布 Flutter 1.0 版本正式发布。截至目前， Flutter 在 Github 上已获得 88000+ 的关注和 11000+ 的 Fork ，其发展速度相当惊人，是今年移动端最火热的开发框架之一。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Flutter 大火背后的原因是什么？为什么越来越多的企业和开发者会选择使用 Flutter？Flutter 会成为跨平台开发的终极之选吗？我认为“ Flutter 并非跨平台终极之选，最初选择 Flutter，不是因为它一定会成为未来终极之选，而是因为它有可能成为不一样的未来。”&lt;/p&gt;

&lt;h2 id=&quot;flutter-大火的原因&quot;&gt;Flutter 大火的原因&lt;/h2&gt;

&lt;p&gt;有人说 Flutter 大火主要原因是它选择了 Dart  语言，Dart 有着高性能的表现和可快速分配内存的能力，能同时支持 JIT 和 AOT 模式，允许在带类型的语言中支持形变和有状态热重载，能编译出高效率的 ARM 机器码指令，Dart 作为面向对象的语言也能让绝大多数开发者更快速上手。我认可 Dart 语言有一定的优势，但这样的优势并非 Dart 独有，我想这更不会是大家选择 Flutter 的核心原因，这是因果倒置。事实上，Dart 是 2011 年推出的，在 Flutter 出现之前，Dart 曾一度几乎被人遗忘。正是因为近年来 Flutter 的火爆，才让 Dart 重新进入大众的视线。Flutter 当初选择 Dart，或者仅因为 Google 的 Flutter 和 Dart 这两个团队离得比较近，交流比较方便。
我认为 Flutter 之所以大火，主要是以下几个原因：&lt;/p&gt;

&lt;h4 id=&quot;1-现有跨平台技术存在缺陷&quot;&gt;1. 现有跨平台技术存在缺陷&lt;/h4&gt;
&lt;p&gt;在移动互联网时代，Android 和 iOS 两大阵营长期共存，再加上体系成熟的 Web 前端技术，导致出现同一个应用需多端重复开发的人力成本问题。正因如此，移动时代下的跨平台技术是一个需要长期研究的课题。如果当下的跨平台技术已经有比较完美的解决方案，可能就没有新技术萌芽的机会。而事实上，目前业界比较成熟的跨平台技术都存在一定的缺陷，比如小程序（WebView）渲染耗时过长，白屏率会影响转化收益，能实现的功能非常受限；再比如 React Native 的性能不足、问题排除难、维护成本高等。而 Flutter 的出现，让这些跨平台开发问题有所改善，它还是 Google 开源的技术，自身也具备一定的热度。另外，一直备受关注且神秘的 Fuchsia 系统在 UI 框架上使用的也是 Flutter，可作为长期战略投入，这也增强了大家对 Flutter 的信心。&lt;/p&gt;

&lt;h4 id=&quot;2-研发效率就是竞争力&quot;&gt;2. 研发效率就是竞争力&lt;/h4&gt;
&lt;p&gt;移动互联网进入下半场，出现一些新兴互联网独角兽、小巨头，在没有历史包袱的情况下，更愿意尝试技术上限更高的新技术。从校招和社招的难度上不难发现：客户端的人才相比之前更为稀缺，尤其是 iOS 工程师。而下半场会有更多竞争和更为激烈的赛道，比如教育等方向。Flutter 本身非常适合从零开始的没有历史包袱的应用开发，对于新业务尤其是在团队人力紧缺的情况下，在技术选型上考虑 Flutter，能加快产品在多端落地、快速试错。&lt;/p&gt;

&lt;h4 id=&quot;3-集漂亮与流畅集于一身&quot;&gt;3. 集漂亮与流畅集于一身&lt;/h4&gt;
&lt;p&gt;Flutter “一出生”就以“UI 漂亮、像素级可控、性能流畅、可媲美原生性能”等特点吸引广大开发者的眼球，自渲染引擎甚至具备开发游戏的能力。移动下半场，没有人口红利，竞争更为激烈，如何能更好地满足用户对高品质、高流畅的需求，便是移动端一种强有力的竞争力。跨平台技术想要拥有更高的流畅度，采用自渲染技术的方案便是更优解，也是一个更为彻底的跨平台技术方向。&lt;/p&gt;

&lt;h2 id=&quot;字节跳动选择-flutter-的初心&quot;&gt;字节跳动选择 Flutter 的初心&lt;/h2&gt;
&lt;p&gt;说到这里，先分享一下 Flutter 最初是如何诞生的故事。Flutter 创始人 Eric 之前在 Chrome 团队工作，期间遇到一些难以解决的问题， 希望 Web 中的一部分能够拥有更加平滑的体验， 为此他花了几周时间做了一个实验，不考虑 Web 的兼容方式，删除了大量为了兼容访问的代码和一些 Web 开发者不常用的功能， 删除到有不少 Web 元素的渲染已经不支持了，然后做了一个基准测试，得出结论是某些关注指标的速度快了 20 倍。于是，Eric 决定再做点什么，后面投入了大量研究和开发，便有了现在的 Flutter 。&lt;/p&gt;

&lt;p&gt;听到这里给人的感觉是，对于 Web 工程师而言 Flutter 应该容易上手。我跟公司很多正在使用或者调研 Flutter 的业务团队做过沟通，发现客户端比前端的同学对 Flutter 接受度更高，我个人从 Android 端技术出身，的确觉得学习 Flutter 还是非常容易上手的，但公司内前端的同学对 Flutter 使用的吐槽会多一点。所以，我认为 Flutter 更像是以客户端视角的跨平台技术，Flutter 与其说是大前端技术，不如说是大移动端技术。Flutter 发展的 Roadmap 也是先全面支持 Android/iOS 端能力，再进一步完善 Web 端能力支持的。&lt;/p&gt;

&lt;p&gt;字节跳动对于客户端技术还是非常重视的，字节跳动有很多客户端工程师，之前客户端深入点的基础技术更多是搞插件化、热修复、性能优化、安全加固等，跨平台方向一直都是前端工程师在不遗余力地推进，属于大前端方向。而 Flutter 是客户端更有主导的跨平台技术方案。另外说明，字节跳动并不是说只有一套跨平台技术栈，公司内部也是多套跨端技术栈并存，也包括自研的方案。&lt;/p&gt;

&lt;p&gt;在字节跳动，跨平台技术并没有形成大规模的落地，之前也提到没有历史包袱，所以在面对跨平台技术选型的时候，更关注跨平台技术的技术上限以及发展潜力，自渲染技术的 Flutter 可以理解为更彻底更纯粹的跨平台技术，伴随着媲美原生的流畅度，这便是我们选择 Flutter 的初心。&lt;/p&gt;

&lt;h2 id=&quot;flutter-落地过程中的坑&quot;&gt;Flutter 落地过程中的“坑”&lt;/h2&gt;
&lt;p&gt;截至目前，字节跳动有很多业务落地了 Flutter 技术方案，包括今日头条、西瓜视频、皮皮虾等 20 多个业务在使用 Flutter 开发，有纯 Flutter 工程，也有 Flutter 与 Native 的混合工程。如果大家想要了解更多业务落地情况，后续我会在今年的 QCon 北京 2020 大会上分享。&lt;/p&gt;

&lt;p&gt;Flutter 虽潜力上限很高，但仍需打磨和雕琢，我们在 Flutter 推动过程中遇到很多问题，比如包体积过大的问题、性能达不到预期、对混合工程的支持不够友好、各宿主 Flutter 引擎版本不一致、基础库不完善、Flutter 改造后各项数据打平等。除此之外，还有很多非技术的困难，比如业务团队并不认可 Flutter 新技术，工程师缺乏 Flutter 经验，担忧审核风险等，都会影响业务方是否采用 Flutter 技术，每一个困难都需要去解决，不然就难以落地。下面就其中两个难点，我来展开聊一下。&lt;/p&gt;

&lt;h4 id=&quot;1-包体积问题&quot;&gt;1. 包体积问题&lt;/h4&gt;
&lt;p&gt;字节跳动内的大型 APP，比如今日头条、抖音等对包体积的增量非常敏感，Flutter 的包体积涉及两个部分，一个是一次性 Flutter 引擎的包体积问题，一个是每次写 Dart 代码比写 OC 代码代码增量的问题。这两个问题对我们来说都非常棘手，我们成立了包体积优化专项进行全力攻坚，同时跟 Google 工程师多次会议沟通，不断精简包体积。最终我们通过一系列优化手段，包含 Data 压缩、编译优化、Skia 裁剪、BoringSSL/ICU 库 / 文字渲染 /libwebp 等库裁剪取得了不少的效果；通过实践我们发现用 OC 代码和 Dart 代码写相同的业务逻辑，Dart 生成的机器码指令比 OC 多，主要在生成的二进制指令头、指令冗余、指令对齐的精简，以及 StackMap 和 CodeSourceMap 的精简等方面。同时我们也向 Google 反馈了这些情况。关于指令精简，可以查看 Issue 进展，里面有记录详细的推进过程：
https://github.com/flutter/flutter/issues/40345&lt;/p&gt;

&lt;h4 id=&quot;2-性能优化问题&quot;&gt;2. 性能优化问题&lt;/h4&gt;
&lt;p&gt;这是我们遇到的棘手问题之一，我们用 Flutter 官方提供的性能分析工具 Timeline 来分析一个比较诡异的性能问题，始终无法发现任何异常。困扰已久，后来干脆重新撸了一遍 Timeline 整个性能分析工具的源码，最终找到了其缺陷，并向 Flutter 社区提及，合入了 10 个 PR ，基于此让我有幸成为了 Flutter Member ，后续会持续向社区贡献更多力量：https://github.com/flutter/flutter/issues/47771.&lt;/p&gt;

&lt;p&gt;Flutter 是一个自渲染的跨平台技术，有着很高的性能上限，但并不代表现在性能各方面都很优秀，毕竟 Flutter 作为一个“新生儿”，还是有一些需要进一步改造的地方。除性能工具改造之外，其实在 Flutter 落地场景中，我们也解决了不少性能问题，同时优化了自身的引擎，比如 UI 预加载策略、Flutter Turbo 技术、Vsync 调度策略等，让引擎提速，争取让 Flutter 性能发挥到极致。&lt;/p&gt;

&lt;h2 id=&quot;flutter-在业务层面的发展阻力&quot;&gt;Flutter 在业务层面的发展阻力&lt;/h2&gt;
&lt;p&gt;引入 Flutter 之后，在公司的业务也创造了不少价值。主要体现在这几个方面：其一，Flutter 多端一致性上表现良好，能做到所见即所得，无需针对某一平台做额外适配工作；其二，热重载技术使得设计团队和工程团队可以非常快速的修改和调试 UI，设计师只需要关注一个平台实现，UI 验收效率明显提高，跨端开发可以提高工程师的人效（有团队初步估算人效大致提升了 1.8 倍）；其三，性能流畅度提升，相较于 H5 版本首屏时间有较大提升，最后，产品商业化数据都有明显的收益，能直观地看到 Flutter 给公司带来的创收。&lt;/p&gt;

&lt;p&gt;不过，现阶段 Flutter 的发展仍有一些阻力：&lt;/p&gt;

&lt;h4 id=&quot;1-flutter-采用的是-dart-语言没能引入前端成熟的生态体系&quot;&gt;1. Flutter 采用的是 Dart 语言，没能引入前端成熟的生态体系&lt;/h4&gt;
&lt;p&gt;作为前端工程师可能更希望是 Flutter 上层采用的是 JavaScript 或者 TypeScript，未来可考虑提供高性能的 Dart 与 JS 互转能力。另外，Flutter 开发对于前端开发工程师而言，还是有一些挑战的，纯前端不一定能 Cover 的技术，比如 Flutter 的一个硬件相关的 Plugin 只在某款手机出现 Bug，如果社区没有现存解决方案，可能就需要花比较大的时间成本去学习 Native 技术，或者请教客户端工程师。&lt;/p&gt;

&lt;h4 id=&quot;2-开源库相对比较欠缺更新频次不足&quot;&gt;2. 开源库相对比较欠缺，更新频次不足&lt;/h4&gt;
&lt;p&gt;Flutter 生态还不够完善，新业务接入需要自己造轮子，尤其是在业务团队对 Flutter 掌握不够熟练的情况下，会增加额外的成本，Flutter 在大中型企业会更容易推广起来，有人力可以去造轮子让公司内其他的业务复用；另外，Flutter 文档有点少，能借鉴的经验不多，未来需加强和鼓励更多开发者加入到生态共建。&lt;/p&gt;

&lt;h4 id=&quot;3-跟原生系统生态存在着一定的竞争关系&quot;&gt;3. 跟原生系统生态存在着一定的竞争关系&lt;/h4&gt;
&lt;p&gt;有朋友跟我说起过这样一件事，看到 Flutter 这么火，Android 开发团队就问他，“大家为什么要用 Flutter 开发 App，我们 Android 哪一点不好，告诉我们，我们可以改进它”。姑且不说他们对跨平台理解不够，但至少能看出原生平台对跨端技术的担忧，不少 Android 团队在推出 Kotlin Multiplatform ，希望能争夺更多市场。
另外，苹果商店的审核风险也是大家所担忧的，官方的公告原意是说应用程序的核心特性和功能必须包含在软件的二进制文件中，而不是通过类似 HTML5 的技术来实现动态更新，苹果要打压的是动态更新技术，考虑到 Flutter 的合规性，Google 主动把 Flutter 的 iOS 动态化能力去掉了，Flutter 最终打包生成的产物就是 IPA，Flutter 其实是完全符合规范的，甚至还有使用 Flutter 开发的应用还被 Apple 推荐过。相反，React Native、Weex、H5 等技术都是一种动态化解决方案，这正是苹果要管控的，目前苹果的态度更多的是不提倡，但也不保证不封杀。即便如此，苹果不希望原生开发生态被其他跨平台技术抢占，苹果也在不断推行 SwiftUI 框架，力图抵挡 Flutter 等跨平台技术对原生开发的蚕食。Flutter 未来要加强推进步伐，让更多的大型 App 通过 Flutter 技术得到收益，只有用户群体上来，未来的地位和话语权才会更高，就像现在小程序，原则上是不符合苹果的审核要求的，但各大型应用基本都上线了小程序功能，目前来看不至于说苹果把小程序直接干掉。&lt;/p&gt;

&lt;h2 id=&quot;flutter-并非跨平台终极之选&quot;&gt;Flutter 并非跨平台终极之选&lt;/h2&gt;
&lt;p&gt;从 Hybrid App 到 React Native，再到 Flutter，跨平台技术层出不穷。目前来看，Flutter 是跨平台开发的最热门技术，但我并不认为 Flutter 就一定是跨平台开发的终极之选，它有着历史局限性，我只能说 Flutter 可能是当下最有潜力的跨平台技术。如果你对性能流畅度有高要求，或者有多个产品希望快速在多端试错迭代，我会推荐你尝试 Flutter。&lt;/p&gt;

&lt;p&gt;未来一段时间，还应该是多套跨平台技术并存的时代， 目前 Flutter 也没有全面做到可以碾压其他跨平台技术，可根据团队以及业务特点来考虑更适合的方案。有一定客户端经验的同学入手 Flutter 会更快一些，如果团队在 React Native 上有很好落地，业务没有遇到性能等瓶颈，且团队缺少客户端能力，建议先做技术调研和沉淀，不要盲目追求新技术，只有当团队有能力且业务有需求的情况下，建议再考虑切换技术栈。&lt;/p&gt;

&lt;p&gt;我们前面提到过，一直备受关注且神秘的 Fuchsia 系统在 UI 框架上使用的也是 Flutter。Fuchsia 是 Google 开发的下一代操作系统。Fuchsia 是采用全新模块化设计思想、跨平台框架技术的系统。它能支持快捷裁剪定制，更能适应未来的多元化设备，包含手机、平板、笔记本、路由器、智能设备、机器人等，Fuchsia 有可能成为一个全新的跨全平台的通用操作系统。&lt;/p&gt;

&lt;p&gt;在现阶段，开始尝试探索和积累沉淀 Flutter 技术能力，并在业务上使用 Flutter 技术的应用，从战略上来将已经处于领先。选择 Flutter，正可谓是“进可攻退可守”，往前进一步，Flutter 应用未来可无缝迁移到 Fuchsia 系统，借用 Fuchsia 系统的能量扩展到更广泛的用户场景；退一步，Flutter 技术自身在 Android/iOS 平台的表现相比其他跨平台技术已经是很优秀。&lt;/p&gt;

&lt;p&gt;最初选择 Flutter，不是因为它一定会成为未来终极之选，而是它有可能成为不一样的未来。&lt;/p&gt;

&lt;h2 id=&quot;flutter-展望终将走向多端一体化&quot;&gt;Flutter 展望：终将走向多端一体化&lt;/h2&gt;
&lt;p&gt;回顾整移动操作系统的演变历程，从塞班功能机到 Android/iOS 智能机，从小屏手机到全面屏、刘海屏、水滴屏。任何系统的演变最终体现在输入和输出两个环节，接收到输入信号后经过操作系统处理后输出信息给用户。从按键式交互到触屏式交互，伴随着塞班系统到 Android 系统的转变，未来的交互方式一定会更加生物智能化，当下的触屏交互可以理解成人类的触觉输入方式，未来将朝着人们更常见的听觉（语音）输入和视觉（身体姿势、表情等）输入，甚至嗅觉（气味变化）输入，这些都会伴随着新的操作系统而诞生。屏幕从小尺寸到大尺寸，并没有引发操作系统变革，因为技术创新是非连续性，非连续性才会引发第二曲线，诞生新技术。从 1960 年大型机，到 1990 年个人笔记本，再到现在的智能手机，设备本身越来越小。未来的设备如果发展非连续变革，可能不再需要实体硬件，随处可输出，一张白纸、一面墙，到那时操作系统的 UI 架构必然会有全新的变化。&lt;/p&gt;

&lt;p&gt;随着科技的发展，5G 时代的到来，人工智能的日趋成熟，端到底会有哪些变化？是否会出现新的操作系统？系统的 UI 架构是否会出现新的变革？Android/iOS 平台是否能与之并存？搭载 Flutter UI 框架的 Fuchsia 系统能否在 IOT 领域以及新的交互方式大放异彩，再领风骚？是否有万物互联互通的超级平台出现？&lt;/p&gt;

&lt;p&gt;技术在不断演变中螺旋前进，平台自身也随之演进，未来 Flutter 会朝着多端一体化的方向发展，能支持更多的端（包括平板、笔记本、智能设备等）。作为一套跨平台的 UI 框架，Flutter 采用自渲染的技术方案，是一个上限很高的跨平台技术，但 Flutter 更重要的是需要提升工程化能力以及生态圈的建设，才能吸引更多的开发者加入。&lt;/p&gt;

&lt;h2 id=&quot;加入我们&quot;&gt;加入我们&lt;/h2&gt;
&lt;p&gt;欢迎更多小伙伴加入字节跳动移动平台部，探索和深耕移动端技术，团队技术氛围浓厚，和我们开创可能成为不一样的未来，Android/iOS/Flutter等在北上深杭招聘各级别岗位，可简历发送至yuanhuihui@bytedance.com, 详细内推岗位见 &lt;a href=&quot;http://gityuan.com/job&quot;&gt;http://gityuan.com/job&lt;/a&gt;。&lt;/p&gt;
</description>
        <pubDate>Thu, 26 Mar 2020 22:12:40 +0000</pubDate>
        <link>http://gityuan.com/2020/03/26/flutter_is_future_or_not/</link>
        <guid isPermaLink="true">http://gityuan.com/2020/03/26/flutter_is_future_or_not/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>彻底掌握Timeline原理(一)</title>
        <description>&lt;h2 id=&quot;一概述&quot;&gt;一、概述&lt;/h2&gt;

&lt;h3 id=&quot;11-timeline事件总览&quot;&gt;1.1 Timeline事件总览&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_timeline/timeline_method.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;C++引擎层层采用的是采用的是Embedder Stream；&lt;/li&gt;
  &lt;li&gt;Dart应用层采用的是Dart Stream;&lt;/li&gt;
  &lt;li&gt;DartVM采用的API Stream；&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;12-c层timeline用法&quot;&gt;1.2 C++层Timeline用法&lt;/h3&gt;

&lt;h4 id=&quot;121-c同步事件&quot;&gt;1.2.1 C++同步事件&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;#include &quot;flutter/fml/trace_event.h&quot;
#define TRACE_EVENT0(category_group, name)           
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)   
#define FML_TRACE_EVENT(category_group, name, ...)                 
fml::tracing::TraceEvent0(category_group, name);
fml::tracing::TraceEventEnd(name);

//示例：
TRACE_EVENT0(&quot;flutter&quot;, &quot;PipelineConsume&quot;);
TRACE_EVENT2(&quot;flutter&quot;, &quot;Framework Workload&quot;,
                &quot;mode&quot;, &quot;basic&quot;, &quot;frame&quot;, FrameParity());
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;122-c异步事件&quot;&gt;1.2.2 C++异步事件&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;#include &quot;flutter/fml/trace_event.h&quot;
#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)
#define TRACE_EVENT_ASYNC_END0(category_group, name, id)
#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, arg1_val)
#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val)
void TraceEventAsyncComplete(TraceArg category_group, TraceArg name,
                             TimePoint begin, TimePoint end)
//示例：
TRACE_EVENT_ASYNC_BEGIN0(&quot;flutter&quot;, &quot;Frame Request Pending&quot;, frame_number);
TRACE_EVENT_ASYNC_END0(&quot;flutter&quot;, &quot;Frame Request Pending&quot;, frame_number_++);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;另外，这里还有一种比较特别的异步事件，事件的开始和结束都是可以手动指定的，TraceEventAsyncComplete 等于TRACE_EVENT_ASYNC_BEGIN0 + TRACE_EVENT_ASYNC_END0，
如下所示：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TraceEventAsyncComplete(TraceArg category_group, TraceArg name,
                             TimePoint begin, TimePoint end);
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;123-c事件流&quot;&gt;1.2.3 C++事件流&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;#include &quot;flutter/fml/trace_event.h&quot;
#define TRACE_FLOW_BEGIN(category, name, id)
#define TRACE_FLOW_STEP(category, name, id)
#define TRACE_FLOW_END(category, name, id)

//示例：
TRACE_FLOW_BEGIN(&quot;flutter&quot;, &quot;PipelineItem&quot;, trace_id_)
TRACE_FLOW_STEP(&quot;flutter&quot;, &quot;PipelineItem&quot;, trace_id_)
TRACE_FLOW_END(&quot;flutter&quot;, &quot;PipelineItem&quot;, trace_id_)
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;124-dartvm事件&quot;&gt;1.2.4 DartVM事件&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;#define API_TIMELINE_DURATION(thread)   
#define API_TIMELINE_BEGIN_END(thread)  

// 示例：
#define T (thread())
API_TIMELINE_DURATION(T);
API_TIMELINE_BEGIN_END(T);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;13-dart层timeline用法&quot;&gt;1.3 dart层Timeline用法&lt;/h3&gt;

&lt;h4 id=&quot;131-dart同步事件&quot;&gt;1.3.1 dart同步事件&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;import 'dart:developer';
Timeline.startSync(String name, {Map arguments, Flow flow});
Timeline.finishSync();

//示例：
Timeline.startSync('Warm-up frame');  //静态方法
Timeline.finishSync();
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;132-dart异步事件&quot;&gt;1.3.2 dart异步事件&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;import 'dart:developer';
TimelineTask.start(String name, {Map arguments});
TimelineTask.finish();

//示例：
final TimelineTask timelineTask = TimelineTask();  //普通方法，需要实例化
timelineTask.start('Warm-up shader');
timelineTask.finish();
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;133-dart事件流&quot;&gt;1.3.3 dart事件流&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Timeline.timeSync('flow_test', () {
  doSomething();
}, flow: flow);

Timeline.timeSync('flow_test', () {
  doSomething();
}, flow: Flow.step(flow.id));

Timeline.timeSync('flow_test', () {
  doSomething();
}, flow: Flow.end(flow.id));
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;14-timelineeventrecorder总览&quot;&gt;1.4 TimelineEventRecorder总览&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_timeline/TimelineRecorder.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;TimelineEventRingRecorder默认大小为32KB，也就是说该Recorder共有512个TimelineEventBlock(事件块)，每个TimelineEventBlock有64个TimelineEvent(事件)。&lt;/p&gt;

&lt;p&gt;1）TimelineEventRecorder：主要还有以下四种：ring, endless, startup,  systrace&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;TimelineEventRingRecorder：这是默认的记录器，其父类TimelineEventFixedBufferRecorder有固定缓存区，
    &lt;ul&gt;
      &lt;li&gt;capacity_: 记录当前缓存区可记录的事件总数，默认值为32KB个；&lt;/li&gt;
      &lt;li&gt;num_blocks_: 记录事件块的数量，默认值为512个，其中每个事件块能记录64个事件；&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;TimelineEventEndlessRecorder：用于记录无上限的trace&lt;/li&gt;
  &lt;li&gt;TimelineEventStartupRecorder：用于记录有限缓存，且记录满则不再记录trace&lt;/li&gt;
  &lt;li&gt;TimelineEventSystraceRecorder：systrace_fd_记录的是/sys/kernel/debug/tracing/trace_marker的文件描述符；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2）TimelineEventBlock&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;length_：记录该事件块已记录的事件个数，每一次StartEvent()则执行加1操作，上限为64；&lt;/li&gt;
  &lt;li&gt;block_index_：记录当前事件块的索引ID，用于无限缓存大小的记录器；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;另外关于时间计数，以Android为例，此处调用的是clock_gettime()系统方法，精确到纳秒，这里有CLOCK_MONOTONIC和CLOCK_THREAD_CPUTIME_ID两种不同的参数，Timeline最终记录的事件事件信息单位是微秒。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;_start：采用参数CLOCK_MONOTONIC，记录从系统启动开始的计时时间点；&lt;/li&gt;
  &lt;li&gt;_startCpu: 采用参数CLOCK_THREAD_CPUTIME_ID，记录当前线程执行代码所花费的CPU时间；&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;二c层timeline&quot;&gt;二、c++层Timeline&lt;/h2&gt;

&lt;p&gt;所有的这些最终都调用Dart_TimelineEvent()方法。&lt;/p&gt;

&lt;h3 id=&quot;21-事件类型&quot;&gt;2.1 事件类型&lt;/h3&gt;

&lt;h4 id=&quot;211-同步事件&quot;&gt;2.1.1 同步事件&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/fml/trace_event.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;#define TRACE_EVENT0(category_group, name)           \
  ::fml::tracing::TraceEvent0(category_group, name); \  //事件开始
  __FML__AUTO_TRACE_END(name)

#define __FML__AUTO_TRACE_END(name)                                  \
  ::fml::tracing::ScopedInstantEnd __FML__TOKEN_CAT__2(__trace_end_, __LINE__)(name);

class ScopedInstantEnd {
 public:
  ScopedInstantEnd(const char* str) : label_(str) {}
  ~ScopedInstantEnd() { TraceEventEnd(label_); }  //事件结束

 private:
  const char* label_;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TraceEvent0(TraceArg category_group, TraceArg name) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),
                    Dart_TimelineGetMicros(), 0,   
                    Dart_Timeline_Event_Begin, 0,
                    nullptr,  nullptr);
}

void TraceEventEnd(TraceArg name) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),
                    Dart_TimelineGetMicros(), 0,   
                    Dart_Timeline_Event_End, 0,
                    nullptr,  nullptr);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;212-异步事件&quot;&gt;2.1.2 异步事件&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/fml/trace_event.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TraceEventAsyncBegin0(TraceArg category_group, TraceArg name, TraceIDArg id) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),
                    Dart_TimelineGetMicros(), id,   
                    Dart_Timeline_Event_Async_Begin, 0,
                    nullptr,  nullptr);
}

void TRACE_EVENT_ASYNC_END0(TraceArg category_group, TraceArg name, TraceIDArg id) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),
                    Dart_TimelineGetMicros(), id,   
                    Dart_Timeline_Event_Async_End, 0,
                    nullptr,  nullptr);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TraceEventAsyncComplete(TraceArg category_group, TraceArg name,
                             TimePoint begin, TimePoint end) {
  auto identifier = TraceNonce();
  if (begin &amp;gt; end) {
    std::swap(begin, end);
  }

  Dart_TimelineEvent(DCHECK_LITERAL(name),                  
                     begin.ToEpochDelta().ToMicroseconds(), identifier,                    
                     Dart_Timeline_Event_Async_Begin, 0,                               
                     nullptr, nullptr);

  Dart_TimelineEvent(DCHECK_LITERAL(name),                  
                     begin.ToEpochDelta().ToMicroseconds(), identifier,                    
                     Dart_Timeline_Event_Async_End, 0,                               
                     nullptr, nullptr);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;213-流事件&quot;&gt;2.1.3 流事件&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/fml/trace_event.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TraceEventFlowBegin0(TraceArg category_group, TraceArg name, TraceIDArg id) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),           
                     Dart_TimelineGetMicros(), id,                             
                     Dart_Timeline_Event_Flow_Begin, 0,                             
                     nullptr, nullptr);
}

void TraceEventFlowStep0(TraceArg category_group, TraceArg name, TraceIDArg id) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),           
                     Dart_TimelineGetMicros(), id,                             
                     Dart_Timeline_Event_Flow_Step, 0,                             
                     nullptr, nullptr);
}

void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) {
  Dart_TimelineEvent(DCHECK_LITERAL(name),           
                     Dart_TimelineGetMicros(), id,                             
                     Dart_Timeline_Event_Flow_End, 0,                             
                     nullptr, nullptr);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可见，所有这些事件最终都是调用Dart_TimelineEvent，不同的主要在事件类型：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dart_Timeline_Event_Begin：同步事件开始&lt;/li&gt;
  &lt;li&gt;Dart_Timeline_Event_End：同步事件结束&lt;/li&gt;
  &lt;li&gt;Dart_Timeline_Event_Async_Begin：同步事件开始&lt;/li&gt;
  &lt;li&gt;Dart_Timeline_Event_Async_End：同步事件结束&lt;/li&gt;
  &lt;li&gt;Dart_Timeline_Event_Flow_Begin：流事件开始&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;时间戳的获取除了TraceEventAsyncComplete()是直接传递的时间参数，其他都是通过Dart_TimelineGetMicros()命令获取执行该命令当下的时间戳，单位是微秒。&lt;/p&gt;

&lt;h4 id=&quot;dart_timelinegetmicros&quot;&gt;Dart_TimelineGetMicros&lt;/h4&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DART_EXPORT int64_t Dart_TimelineGetMicros() {
  return OS::GetCurrentMonotonicMicros();
}

//以Android为例
int64_t OS::GetCurrentMonotonicMicros() {
  int64_t ticks = GetCurrentMonotonicTicks();
  return ticks / kNanosecondsPerMicrosecond;
}

int64_t OS::GetCurrentMonotonicTicks() {
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &amp;amp;ts) != 0) {
    return 0;
  }
  int64_t result = ts.tv_sec;
  result *= kNanosecondsPerSecond;
  result += ts.tv_nsec;
  return result;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;通过clock_gettime系统调用获取CLOCK_MONOTONIC类型的时间，也就是系统从启动到现在的时间戳；&lt;/p&gt;

&lt;h3 id=&quot;22-dart_timelineevent&quot;&gt;2.2 Dart_TimelineEvent&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dart_api_impl.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DART_EXPORT void Dart_TimelineEvent(const char* label,
                                    int64_t timestamp0,
                                    int64_t timestamp1_or_async_id,
                                    Dart_Timeline_Event_Type type,
                                    intptr_t argument_count,
                                    const char** argument_names,
                                    const char** argument_values) {
#if defined(SUPPORT_TIMELINE)
  //采用的是Embedder Stream
  TimelineStream* stream = Timeline::GetEmbedderStream();
  //[见小节2.3.1]
  TimelineEvent* event = stream-&amp;gt;StartEvent();

  switch (type) {
    case Dart_Timeline_Event_Begin:
      event-&amp;gt;Begin(label, timestamp0); //[见小节2.3.3]
      break;
    case Dart_Timeline_Event_End:
      event-&amp;gt;End(label, timestamp0);
      break;
    case Dart_Timeline_Event_Instant:
      event-&amp;gt;Instant(label, timestamp0);
      break;
    case Dart_Timeline_Event_Duration:
      event-&amp;gt;Duration(label, timestamp0, timestamp1_or_async_id);
      break;
    case Dart_Timeline_Event_Async_Begin:
      event-&amp;gt;AsyncBegin(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Async_End:
      event-&amp;gt;AsyncEnd(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Async_Instant:
      event-&amp;gt;AsyncInstant(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Counter:
      event-&amp;gt;Counter(label, timestamp0);
      break;
    case Dart_Timeline_Event_Flow_Begin:
      event-&amp;gt;FlowBegin(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Flow_Step:
      event-&amp;gt;FlowStep(label, timestamp1_or_async_id, timestamp0);
      break;
    case Dart_Timeline_Event_Flow_End:
      event-&amp;gt;FlowEnd(label, timestamp1_or_async_id, timestamp0);
      break;
    default:
      FATAL(&quot;Unknown Dart_Timeline_Event_Type&quot;);
  }
  event-&amp;gt;SetNumArguments(argument_count);
  for (intptr_t i = 0; i &amp;lt; argument_count; i++) {
    event-&amp;gt;CopyArgument(i, argument_names[i], argument_values[i]);
  }
  // [见小节2.3.4]
  event-&amp;gt;Complete();  
#endif
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;先以目前timeline的默认记录器TimelineEventRingRecorder来展开说明。&lt;/p&gt;

&lt;h3 id=&quot;23-ring类型记录器&quot;&gt;2.3 ring类型记录器&lt;/h3&gt;

&lt;h4 id=&quot;231-startevent&quot;&gt;2.3.1 StartEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineEvent* TimelineEventFixedBufferRecorder::StartEvent() {
  return ThreadBlockStartEvent();  //【见下方】
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
  OSThread* thread = OSThread::Current();
  Mutex* thread_block_lock = thread-&amp;gt;timeline_block_lock();
  thread_block_lock-&amp;gt;Lock();   //这个锁会一直持有，直到调用CompleteEvent()

  TimelineEventBlock* thread_block = thread-&amp;gt;timeline_block();
  if ((thread_block != NULL) &amp;amp;&amp;amp; thread_block-&amp;gt;IsFull()) {
    MutexLocker ml(&amp;amp;lock_); //加锁，保证每次只有一个线程申请新的事件块
    thread_block-&amp;gt;Finish();  //该事件块已满【见小节2.3.5】
    thread_block = GetNewBlockLocked(); //分配新的事件块
    thread-&amp;gt;set_timeline_block(thread_block);
  } else if (thread_block == NULL) {
    MutexLocker ml(&amp;amp;lock_);
    thread_block = GetNewBlockLocked(); //没有事件块，则创建事件块
    thread-&amp;gt;set_timeline_block(thread_block);
  }
  if (thread_block != NULL) {
    //持锁状态退出该函数  见下方】
    TimelineEvent* event = thread_block-&amp;gt;StartEvent();
    return event;
  }
  thread_block_lock-&amp;gt;Unlock(); //没有任何事件，则释放锁
  return NULL;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineEvent* TimelineEventBlock::StartEvent() {
  return &amp;amp;events_[length_++];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;说明：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;如果当前线程中的thread_block为空，则创建新的事件块，并将当前线程id记录到该事件块，同时将该事件块再记录其成员变量timeline_block_事件块；&lt;/li&gt;
  &lt;li&gt;如果当前线程中的thread_block已满，则先将该事件块finish，再创建新的事件块；&lt;/li&gt;
  &lt;li&gt;从当前线程的事件块中分配一个可用的TimelineEvent事件；&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;232-getnewblocklocked&quot;&gt;2.3.2 GetNewBlockLocked&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() {
  if (block_cursor_ == num_blocks_) {
    block_cursor_ = 0;
  }
  TimelineEventBlock* block = &amp;amp;blocks_[block_cursor_++];
  block-&amp;gt;Reset(); //事件重置
  block-&amp;gt;Open(); // [见下文]
  return block;
}

void TimelineEventBlock::Open() {
  OSThread* os_thread = OSThread::Current();
  //将当前线程id记录到该事件块中的thread_id_
  thread_id_ = os_thread-&amp;gt;trace_id();
  in_use_ = true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OSThread对象里面有一个TimelineEventBlock指针，记录着当前正在操作的事件块。事件块里面有一个events_，记录着TimelineEvent数组，大小为kBlockSize=64。&lt;/p&gt;

&lt;h4 id=&quot;233-timelineeventbegin&quot;&gt;2.3.3 TimelineEvent::Begin&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void Begin(const char* label,
           int64_t micros = OS::GetCurrentMonotonicMicros(),
           int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
void AsyncBegin(const char* label,
    int64_t async_id,
    int64_t micros = OS::GetCurrentMonotonicMicros());
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;事件定义过程会设置默认值，同步与异步的区别是异步事件会记录async_id，同步事件会记录当前线程的cpu运行时间戳。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::Begin(const char* label,
                          int64_t micros,
                          int64_t thread_micros) {
  Init(kBegin, label);
  set_timestamp0(micros);  //系统启动后运行的时间戳
  set_thread_timestamp0(thread_micros); //该线程CPU运行的时间戳
}

void TimelineEvent::End(const char* label,
                        int64_t micros,
                        int64_t thread_micros) {
  Init(kEnd, label);
  set_timestamp0(micros); //系统启动后运行的时间戳
  set_thread_timestamp0(thread_micros);//该线程CPU运行的时间戳
}

void TimelineEvent::AsyncBegin(const char* label,
                               int64_t async_id,
                               int64_t micros) {
  Init(kAsyncBegin, label);
  set_timestamp0(micros);
  set_timestamp1(async_id); //async_id记录到timestamp1_
}

void TimelineEvent::AsyncEnd(const char* label,
                             int64_t async_id,
                             int64_t micros) {
  Init(kAsyncEnd, label);
  set_timestamp0(micros);
  set_timestamp1(async_id); //async_id记录到timestamp1_
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::Init(EventType event_type, const char* label) {
  state_ = 0;
  timestamp0_ = 0;
  timestamp1_ = 0;
  thread_timestamp0_ = -1;
  thread_timestamp1_ = -1;
  OSThread* os_thread = OSThread::Current();
  thread_ = os_thread-&amp;gt;trace_id();  //记录线程id
  Isolate* isolate = Isolate::Current();
  if (isolate != NULL) {
    isolate_id_ = isolate-&amp;gt;main_port(); //记录isolate端口号
  } else {
    isolate_id_ = ILLEGAL_PORT;
  }
  label_ = label; //事件标签名
  arguments_.Free();
  set_event_type(event_type); //事件类型，比如kBegin，kEnd
  set_pre_serialized_args(false);
  set_owns_label(false);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;234-complete&quot;&gt;2.3.4 Complete&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::Complete() {
  TimelineEventRecorder* recorder = Timeline::recorder();
  if (recorder != NULL) {
    recorder-&amp;gt;CompleteEvent(this); //[见下文]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) {
  ThreadBlockCompleteEvent(event);  //[见下文]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) {
  OSThread* thread = OSThread::Current();
  Mutex* thread_block_lock = thread-&amp;gt;timeline_block_lock();
  thread_block_lock-&amp;gt;Unlock(); //释放同步锁
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;当OSThread的thread_block写满，则需要执行Finish()，将该事件块的数据发送给ServiceIsolate来处理，如下所示。&lt;/p&gt;

&lt;h4 id=&quot;235-timelineeventblockfinish&quot;&gt;2.3.5 TimelineEventBlock::Finish&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEventBlock::Finish() {
  in_use_ = false;
#ifndef PRODUCT
  if (Service::timeline_stream.enabled()) {
    ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents);
    service_event.set_timeline_event_block(this);
    Service::HandleEvent(&amp;amp;service_event); //[见下文]
  }
#endif
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;236-servicehandleevent&quot;&gt;2.3.6 Service::HandleEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void Service::HandleEvent(ServiceEvent* event) {
  if (event-&amp;gt;stream_info() != NULL &amp;amp;&amp;amp; !event-&amp;gt;stream_info()-&amp;gt;enabled()) {
    return; //当没有地方监听事件流，则忽略
  }
  if (!ServiceIsolate::IsRunning()) {
    return; //当ServiceIsolate没有运行，则停止
  }
  JSONStream js;
  const char* stream_id = event-&amp;gt;stream_id();
  {
    JSONObject jsobj(&amp;amp;js);
    jsobj.AddProperty(&quot;jsonrpc&quot;, &quot;2.0&quot;);
    jsobj.AddProperty(&quot;method&quot;, &quot;streamNotify&quot;);
    JSONObject params(&amp;amp;jsobj, &quot;params&quot;);
    params.AddProperty(&quot;streamId&quot;, stream_id);
    params.AddProperty(&quot;event&quot;, event);
  }
  //此处isoalte为空，[见小节]
  PostEvent(event-&amp;gt;isolate(), stream_id, event-&amp;gt;KindAsCString(), &amp;amp;js);

  if (event-&amp;gt;stream_info() != nullptr &amp;amp;&amp;amp;
      event-&amp;gt;stream_info()-&amp;gt;consumer() != nullptr) {
    auto length = js.buffer()-&amp;gt;length();
    event-&amp;gt;stream_info()-&amp;gt;consumer()(
        reinterpret_cast&amp;lt;uint8_t*&amp;gt;(js.buffer()-&amp;gt;buf()), length);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可通过Dart_SetNativeServiceStreamCallback()来设置Dart_NativeStreamConsumer回调方法。&lt;/p&gt;

&lt;h4 id=&quot;237-servicepostevent&quot;&gt;2.3.7 Service::PostEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void Service::PostEvent(Isolate* isolate,
                        const char* stream_id,
                        const char* kind,
                        JSONStream* event) {
  //消息格式[&amp;lt;stream id&amp;gt;, &amp;lt;json string&amp;gt;]
  Dart_CObject list_cobj;
  Dart_CObject* list_values[2];
  list_cobj.type = Dart_CObject_kArray;
  list_cobj.value.as_array.length = 2;
  list_cobj.value.as_array.values = list_values;

  Dart_CObject stream_id_cobj;
  stream_id_cobj.type = Dart_CObject_kString;
  stream_id_cobj.value.as_string = const_cast&amp;lt;char*&amp;gt;(stream_id); //stream_id
  list_values[0] = &amp;amp;stream_id_cobj;

  Dart_CObject json_cobj;
  json_cobj.type = Dart_CObject_kString;
  json_cobj.value.as_string = const_cast&amp;lt;char*&amp;gt;(event-&amp;gt;ToCString()); //event
  list_values[1] = &amp;amp;json_cobj;

  auto thread = Thread::Current();
  if (thread != nullptr) {
    TransitionVMToNative transition(thread);
    //向service isolate发送事件
    Dart_PostCObject(ServiceIsolate::Port(), &amp;amp;list_cobj);
  } else {
    Dart_PostCObject(ServiceIsolate::Port(), &amp;amp;list_cobj);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;238-dart_postcobject&quot;&gt;2.3.8 Dart_PostCObject&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
  return PostCObjectHelper(port_id, message);
}

static bool PostCObjectHelper(Dart_Port port_id, Dart_CObject* message) {
  ApiMessageWriter writer;
  Message* msg = writer.WriteCMessage(message, port_id, Message::kNormalPriority);
  if (msg == NULL) {  
    return false;
  }
  return PortMap::PostMessage(msg);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最终会把数据传递给ServiceIsolate来进行处理。&lt;/p&gt;

&lt;h3 id=&quot;24-systrace类型记录器&quot;&gt;2.4 systrace类型记录器&lt;/h3&gt;

&lt;h4 id=&quot;241-startevent&quot;&gt;2.4.1 StartEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineEvent* TimelineEventPlatformRecorder::StartEvent() {
  TimelineEvent* event = new TimelineEvent();
  return event;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;242-timelineevent初始化&quot;&gt;2.4.2 TimelineEvent初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineEvent::TimelineEvent()
    : timestamp0_(0),
      timestamp1_(0),
      thread_timestamp0_(-1),
      thread_timestamp1_(-1),
      state_(0),
      label_(NULL),
      stream_(NULL),
      thread_(OSThread::kInvalidThreadId),
      isolate_id_(ILLEGAL_PORT) {}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;243-timelineeventbegin&quot;&gt;2.4.3 TimelineEvent::Begin&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::Begin(const char* label,
                          int64_t micros,
                          int64_t thread_micros) {
  Init(kBegin, label);
  set_timestamp0(micros);  //系统启动后运行的时间戳
  set_thread_timestamp0(thread_micros); //该线程CPU运行的时间戳
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;244-complete&quot;&gt;2.4.4 Complete&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::Complete() {
  TimelineEventRecorder* recorder = Timeline::recorder();
  if (recorder != NULL) {
    recorder-&amp;gt;CompleteEvent(this); //[见下文]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
  OnEvent(event);
  delete event;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;245-onevent&quot;&gt;2.4.5 OnEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline_android.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEventSystraceRecorder::OnEvent(TimelineEvent* event) {
  const intptr_t kBufferLength = 1024;
  char buffer[kBufferLength];
  //[小节2.4.6]
  const intptr_t event_length = PrintSystrace(event, &amp;amp;buffer[0], kBufferLength);
  if (event_length &amp;gt; 0) {
    ssize_t result;
    do {
      result = write(systrace_fd_, buffer, event_length);
    } while ((result == -1L) &amp;amp;&amp;amp; (errno == EINTR));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处的systrace_fd_是指/sys/kernel/debug/tracing/trace_marker，也就是ftrace的buffer。&lt;/p&gt;

&lt;p&gt;其中PrintSystrace过程如下所示：&lt;/p&gt;

&lt;h4 id=&quot;246-printsystrace&quot;&gt;2.4.6 PrintSystrace&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;intptr_t TimelineEventSystraceRecorder::PrintSystrace(TimelineEvent* event,
                                                      char* buffer,
                                                      intptr_t buffer_size) {
  buffer[0] = '\0';
  intptr_t length = 0;
  int64_t pid = OS::ProcessId();
  switch (event-&amp;gt;event_type()) {
    case TimelineEvent::kBegin: {
      length = Utils::SNPrint(buffer, buffer_size, &quot;B|%&quot; Pd64 &quot;|%s&quot;, pid,
                              event-&amp;gt;label());
      break;
    }
    case TimelineEvent::kEnd: {
      length = Utils::SNPrint(buffer, buffer_size, &quot;E&quot;);
      break;
    }
    case TimelineEvent::kCounter: {
      if (event-&amp;gt;arguments_length() &amp;gt; 0) {
        length = Utils::SNPrint(buffer, buffer_size, &quot;C|%&quot; Pd64 &quot;|%s|%s&quot;, pid,
                                event-&amp;gt;label(), event-&amp;gt;arguments()[0].value);
      }
      break;
    }
    default:
      break;
  }
  return length;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可见kBegin、kEnd、kCounter记录的信息如下所示：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;B|pid|name
E
C|pid|name|count
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;25-小结&quot;&gt;2.5 小结&lt;/h3&gt;

&lt;p&gt;每一个Timeline时间的执行流程：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;通过StartEvent来获取TimelineEvent；&lt;/li&gt;
  &lt;li&gt;根据不同事件类型来填充相应event；&lt;/li&gt;
  &lt;li&gt;最后执行Complete；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ring和endless、startup记录器实现方式非常相近，都需要ServiceIsolate才能工作，其核心区别是GetNewBlockLocked()中buffer分配的方式。ring和startup都是采用的是固定大小，ring是在buffer已满的情况下循环写；startup则是写满buffer则不再写入；endless采用的是无上限的buffer空间。
systrace实现方式则跟前三者完全不同，systrace依赖的是linux底层的ftrace，无需额外开辟buffer。&lt;/p&gt;

&lt;h2 id=&quot;三dart层timeline&quot;&gt;三、dart层Timeline&lt;/h2&gt;

&lt;h3 id=&quot;31-同步事件类型&quot;&gt;3.1 同步事件类型&lt;/h3&gt;

&lt;h4 id=&quot;311-timelinestartsync&quot;&gt;3.1.1 Timeline.startSync&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/developer/timeline.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Timeline {
  static final List&amp;lt;_SyncBlock&amp;gt; _stack = new List&amp;lt;_SyncBlock&amp;gt;();

  static void startSync(String name, {Map arguments, Flow flow}) {
    if (!_hasTimeline) return;
    if (!_isDartStreamEnabled()) {
      _stack.add(null);
      return;
    }
    //创建同步块
    var block = new _SyncBlock._(name, _getTraceClock(), _getThreadCpuClock());
    if (arguments != null) {
      block._arguments = arguments;
    }
    if (flow != null) {
      block.flow = flow;
    }
    _stack.add(block);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;该过程如果出现_stack列表为空，则会抛出异常，说明调用startSync/finishSync不是成对出现；&lt;/li&gt;
  &lt;li&gt;调用finishSync()过程，从列表弹出最近加入的一个数据然后调用其finish()方法；&lt;/li&gt;
  &lt;li&gt;每一条timeline都是通过创建_SyncBlock对象来记录，并保存到_stack列表。其中_hasTimeline是通过判断dart.developer.timeline值来决定，默认为true。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;关于时间的两个方法如下所示：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0, 0) {
  return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew);
}

DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0, 0) {
  return Integer::New(OS::GetCurrentThreadCPUMicros(), Heap::kNew);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;312-_syncblock初始化&quot;&gt;3.1.2 _SyncBlock初始化&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _SyncBlock {
  final String category = 'Dart';
  final String name;
  Map _arguments;
  final int _start;  //启动运行时间戳
  final int _startCpu; //该线程CPU运行时间戳

  Flow _flow;

  _SyncBlock._(this.name, this._start, this._startCpu);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;313-timelinefinishsync&quot;&gt;3.1.3 Timeline.finishSync&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/developer/timeline.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Timeline {

  static void finishSync() {
    if (!_hasTimeline) {
      return;
    }
    if (_stack.length == 0) {
      throw new StateError('Uneven calls to startSync and finishSync');
    }
    var block = _stack.removeLast();
    block.finish();  //[见小节]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;314-_syncblockfinish&quot;&gt;3.1.4 _SyncBlock.finish&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/developer/timeline.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _SyncBlock {

  void finish() {
    // [见小节]
    _reportCompleteEvent(
        _start, _startCpu, category, name, _argumentsAsJson(_arguments));
    if (_flow != null) {
      _reportFlowEvent(_start, _startCpu, category, name, _flow._type, _flow.id,
          _argumentsAsJson(null));
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;315-_reportcompleteevent&quot;&gt;3.1.5 _reportCompleteEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/lib/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 0, 5) {
#if defined(SUPPORT_TIMELINE)
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments-&amp;gt;NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments-&amp;gt;NativeArgAt(1));
  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments-&amp;gt;NativeArgAt(2));
  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments-&amp;gt;NativeArgAt(3));
  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments-&amp;gt;NativeArgAt(4));

  TimelineEventRecorder* recorder = Timeline::recorder();
  //获取TimelineEvent对象
  TimelineEvent* event = Timeline::GetDartStream()-&amp;gt;StartEvent();
  //见小节
  DartTimelineEventHelpers::ReportCompleteEvent(
      thread, event, start.AsInt64Value(), start_cpu.AsInt64Value(),
      category.ToCString(), name.ToMallocCString(), args.ToMallocCString());
#endif
  return Object::null();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;316-reportcompleteevent&quot;&gt;3.1.6 ReportCompleteEvent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void DartTimelineEventHelpers::ReportCompleteEvent(Thread* thread,
                                                   TimelineEvent* event,
                                                   int64_t start,
                                                   int64_t start_cpu,
                                                   const char* category,
                                                   char* name,
                                                   char* args) {
  const int64_t end = OS::GetCurrentMonotonicMicros();
  const int64_t end_cpu = OS::GetCurrentThreadCPUMicros();
  //将四个时间戳记录到TimelineEvent
  event-&amp;gt;Duration(name, start, end, start_cpu, end_cpu);
  event-&amp;gt;set_owns_label(true);
  // 见小节
  event-&amp;gt;CompleteWithPreSerializedArgs(args);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::Duration(const char* label,
                             int64_t start_micros,
                             int64_t end_micros,
                             int64_t thread_start_micros,
                             int64_t thread_end_micros) {
  Init(kDuration, label);
  set_timestamp0(start_micros);
  set_timestamp1(end_micros);
  set_thread_timestamp0(thread_start_micros);
  set_thread_timestamp1(thread_end_micros);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将名字记录到TimelineEvent的成员变量label_，将四个时间戳记录到TimelineEvent的相应成员变量。&lt;/p&gt;

&lt;h4 id=&quot;317-completewithpreserializedargs&quot;&gt;3.1.7 CompleteWithPreSerializedArgs&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/timeline.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::CompleteWithPreSerializedArgs(char* args_json) {
  set_pre_serialized_args(true);
  SetNumArguments(1);
  SetArgument(0, &quot;Dart Arguments&quot;, args_json);
  Complete();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接着执行Complete()，根据不同的recorder回到了前面已介绍[小节2.3.4]/[小节2.4.4]过程。&lt;/p&gt;

&lt;h3 id=&quot;32-异步事件类型&quot;&gt;3.2 异步事件类型&lt;/h3&gt;

&lt;h4 id=&quot;321-timelinetaskstart&quot;&gt;3.2.1 TimelineTask.start&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class TimelineTask {
  final int _taskId;
  final List&amp;lt;_AsyncBlock&amp;gt; _stack = [];

  //需要先初始化
  TimelineTask() : _taskId = _getNextAsyncId() {}

  void start(String name, {Map arguments}) {
    if (!_hasTimeline) return;
    var block = new _AsyncBlock._(name, _taskId);
    if (arguments != null) {
      block._arguments = arguments;
    }
    _stack.add(block);
    block._start();  //[见小节]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;322-_asyncblock_start&quot;&gt;3.2.2 _AsyncBlock._start&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _AsyncBlock {
  final String category = 'Dart';
  final String name;
  final int _taskId;
  Map _arguments;

  void _start() {
    _reportTaskEvent(
        _getTraceClock(), _taskId, 'b', category, name, _argumentsAsJson(null));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;_AsyncBlock相比_SyncBlock少了，少了两个时间相关的成员变量，多了一个记录taskid的成员变量&lt;/p&gt;

&lt;h4 id=&quot;323-timelinetaskfinish&quot;&gt;3.2.3 TimelineTask.finish&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class TimelineTask {

  void finish() {
    if (!_hasTimeline) {
      return;
    }
    var block = _stack.removeLast();
    block._finish(); //[见小节]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;324-_asyncblock_finish&quot;&gt;3.2.4 _AsyncBlock._finish&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class TimelineTask {

  void _finish() {
    _reportTaskEvent(_getTraceClock(), _taskId, 'e', category, name,
        _argumentsAsJson(_arguments));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;325-_reporttaskevent&quot;&gt;3.2.5 _reportTaskEvent&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 6) {
#if defined(SUPPORT_TIMELINE)
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments-&amp;gt;NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments-&amp;gt;NativeArgAt(1));
  GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments-&amp;gt;NativeArgAt(2));
  GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments-&amp;gt;NativeArgAt(3));
  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments-&amp;gt;NativeArgAt(4));
  GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments-&amp;gt;NativeArgAt(5));

  TimelineEventRecorder* recorder = Timeline::recorder();
  //获取TimelineEvent对象
  TimelineEvent* event = Timeline::GetDartStream()-&amp;gt;StartEvent();
  //见小节
  DartTimelineEventHelpers::ReportTaskEvent(
      thread, event, start.AsInt64Value(), id.AsInt64Value(), phase.ToCString(),
      category.ToCString(), name.ToMallocCString(), args.ToMallocCString());
#endif  // SUPPORT_TIMELINE
  return Object::null();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;326-reporttaskevent&quot;&gt;3.2.6 ReportTaskEvent&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void DartTimelineEventHelpers::ReportTaskEvent(Thread* thread,
                                               TimelineEvent* event,
                                               int64_t start,
                                               int64_t id,
                                               const char* phase,
                                               const char* category,
                                               char* name,
                                               char* args) {
  switch (phase[0]) {
    case 'n':
      event-&amp;gt;AsyncInstant(name, id, start);
      break;
    case 'b':
      event-&amp;gt;AsyncBegin(name, id, start);
      break;
    case 'e':
      event-&amp;gt;AsyncEnd(name, id, start);
      break;
    default:
      UNREACHABLE();
  }
  event-&amp;gt;set_owns_label(true);
  event-&amp;gt;CompleteWithPreSerializedArgs(args);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;327-completewithpreserializedargs&quot;&gt;3.2.7 CompleteWithPreSerializedArgs&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineEvent::CompleteWithPreSerializedArgs(char* args_json) {
  set_pre_serialized_args(true);
  SetNumArguments(1);
  SetArgument(0, &quot;Dart Arguments&quot;, args_json);
  Complete();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接着执行Complete()，根据不同的recorder回到了前面已介绍[小节2.3.4]/[小节2.4.4]过程。&lt;/p&gt;

&lt;h2 id=&quot;四dart虚拟机timeline&quot;&gt;四、dart虚拟机Timeline&lt;/h2&gt;

&lt;p&gt;这两个宏目前主要用于dart_api_impl.cc文件&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;#define API_TIMELINE_DURATION(thread)                                          \
  TimelineDurationScope api_tds(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
#define API_TIMELINE_BEGIN_END(thread)                                         \
  TimelineBeginEndScope api_tbes(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;41-api_timeline_duration&quot;&gt;4.1 API_TIMELINE_DURATION&lt;/h3&gt;

&lt;h4 id=&quot;411-timelinedurationscope初始化&quot;&gt;4.1.1 TimelineDurationScope初始化&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineDurationScope::TimelineDurationScope(Thread* thread,
                                             TimelineStream* stream,
                                             const char* label)
    : TimelineEventScope(thread, stream, label) {
  if (!enabled()) {
    return;
  }
  timestamp_ = OS::GetCurrentMonotonicMicros();
  thread_timestamp_ = OS::GetCurrentThreadCPUMicros();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该timeline事件的标签名为CURRENT_FUNC，也就是函数名；&lt;/p&gt;

&lt;h4 id=&quot;412-timelinedurationscope析构&quot;&gt;4.1.2 TimelineDurationScope析构&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineDurationScope::~TimelineDurationScope() {
  if (!ShouldEmitEvent()) {
    return;
  }
  TimelineEvent* event = stream()-&amp;gt;StartEvent();
  if (event == NULL) {
    return;
  }
  //创建事件
  event-&amp;gt;Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(),
                  thread_timestamp_, OS::GetCurrentThreadCPUMicros());
  StealArguments(event);
  //事件完成
  event-&amp;gt;Complete();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;42-api_timeline_begin_end&quot;&gt;4.2 API_TIMELINE_BEGIN_END&lt;/h3&gt;

&lt;h4 id=&quot;411-timelinebeginendscope&quot;&gt;4.1.1 TimelineBeginEndScope&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread,
                                             TimelineStream* stream,
                                             const char* label)
    : TimelineEventScope(thread, stream, label) {
  EmitBegin();
}

TimelineBeginEndScope::~TimelineBeginEndScope() {
  EmitEnd();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该timeline事件的标签名为CURRENT_FUNC，也就是函数名&lt;/p&gt;

&lt;h4 id=&quot;412-emitbegin&quot;&gt;4.1.2 EmitBegin&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineBeginEndScope::EmitBegin() {
  if (!ShouldEmitEvent()) {
    return;
  }
  TimelineEvent* event = stream()-&amp;gt;StartEvent();
  if (event == NULL) {
    set_enabled(false);
    return;
  }
  event-&amp;gt;Begin(label());  //事件开始
  event-&amp;gt;Complete();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;413-emitend&quot;&gt;4.1.3 EmitEnd&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void TimelineBeginEndScope::EmitEnd() {
  if (!ShouldEmitEvent()) {
    return;
  }
  TimelineEvent* event = stream()-&amp;gt;StartEvent();
  if (event == NULL) {
    set_enabled(false);
    return;
  }
  event-&amp;gt;End(label());  //事件结束
  StealArguments(event);
  event-&amp;gt;Complete();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;对于timeline来说功能是一致的，但对于systrace则不同，因为事件的方式不同，建议时候用API_TIMELINE_BEGIN_END，不推荐使用API_TIMELINE_DURATION。&lt;/p&gt;

&lt;h2 id=&quot;五总结&quot;&gt;五、总结&lt;/h2&gt;

&lt;p&gt;TimelineEventRecorder：主要还有以下四种：ring, endless, startup, systrace，本身timeline是能够转换为systrace的，但是在转换过程中有很多坑，需要去解决，下一篇文章再进一步讲解如何解决对systrace更友好的支持。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;附录：&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;flutter/fml/trace_event.cc
third_party/dart/sdk/lib/developer/timeline.dart
third_party/dart/runtime/lib/timeline.cc

third_party/dart/runtime/vm/
  - dart_api_impl.cc
  - timeline.cc
  - timeline_android.cc
  - service.cc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sat, 19 Oct 2019 22:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/10/19/timeline/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/10/19/timeline/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>ServiceIsolate工作原理</title>
        <description>&lt;h2 id=&quot;一概述&quot;&gt;一、概述&lt;/h2&gt;

&lt;p&gt;在前面文章&lt;a href=&quot;http://gityuan.com/2019/06/23/dart-vm/&quot;&gt;深入理解Dart虚拟机启动&lt;/a&gt;中，有讲到Dart虚拟机中有一个比较重要的isolate，创建的isolate名为”vm-service”，运行在独立的线程，也就是ServiceIsolate，这是用于系统调试相关功能的一个isolate，提供虚拟机相关服务，  比如hot reload，timeline等。这里先来看看ServiceIsolate的启动过程以及监听处理流程。&lt;/p&gt;

&lt;h2 id=&quot;二启动serviceisolate&quot;&gt;二、启动ServiceIsolate&lt;/h2&gt;

&lt;p&gt;在dart虚拟机启动过程，会执行Dart::Init()操作，该过程中初始化timeline以及在线程池中启动ServiceIsolate。&lt;/p&gt;

&lt;h3 id=&quot;21-dartinit&quot;&gt;2.1 Dart::Init&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dart.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;char* Dart::Init(Dart_IsolateCreateCallback create,
                 Dart_IsolateShutdownCallback shutdown,
                 Dart_IsolateCleanupCallback cleanup,
                 Dart_ThreadExitCallback thread_exit,
                 ...) {
  ...
#if defined(SUPPORT_TIMELINE)
  Timeline::Init();
#endif

  Isolate::SetCreateCallback(create);
  Isolate::SetShutdownCallback(shutdown);
  Isolate::SetCleanupCallback(cleanup);
  const bool is_dart2_aot_precompiler = FLAG_precompiled_mode &amp;amp;&amp;amp; !kDartPrecompiledRuntime;
  if (!is_dart2_aot_precompiler &amp;amp;&amp;amp;
      (FLAG_support_service || !kDartPrecompiledRuntime)) {
    ServiceIsolate::Run();  //[见小节]
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;启动ServiceIsolate的条件，需要满足以下两者之一：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;当kDartPrecompiledRuntime = true，且FLAG_support_service = true；&lt;/li&gt;
  &lt;li&gt;当kDartPrecompiledRuntime = false，且FLAG_precompiled_mode = false；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;再来看一看DartVM初始化过程&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DartVM::DartVM(std::shared_ptr&amp;lt;const DartVMData&amp;gt; vm_data,
               std::shared_ptr&amp;lt;IsolateNameServer&amp;gt; isolate_name_server) {
    ...
    TRACE_EVENT0(&quot;flutter&quot;, &quot;Dart_Initialize&quot;);
    Dart_InitializeParams params = {};
    params.create = reinterpret_cast&amp;lt;decltype(params.create)&amp;gt;(
    DartIsolate::DartIsolateCreateCallback);
    params.shutdown = reinterpret_cast&amp;lt;decltype(params.shutdown)&amp;gt;(
    DartIsolate::DartIsolateShutdownCallback);
    params.cleanup = reinterpret_cast&amp;lt;decltype(params.cleanup)&amp;gt;(
    DartIsolate::DartIsolateCleanupCallback);
    params.thread_exit = ThreadExitCallback;
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可见，ServiceIsolate的创建callback方法是指DartIsolate::DartIsolateCreateCallback()，后面会用到这个信息。&lt;/p&gt;

&lt;h3 id=&quot;22-serviceisolaterun&quot;&gt;2.2 ServiceIsolate::Run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service_isolate.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void ServiceIsolate::Run() {
  {
    MonitorLocker ml(monitor_);
    state_ = kStarting;
    ml.NotifyAll();
  }
  //将任务交给线程池中的worker线程来执行任务[见小节]
  bool task_started = Dart::thread_pool()-&amp;gt;Run(new RunServiceTask());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将RunServiceTask任务交给线程池中的worker线程来执行任务，过程会创建创建名为“vm-service”的isolate。&lt;/p&gt;

&lt;h3 id=&quot;23-runservicetask&quot;&gt;2.3 RunServiceTask&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service_isolate.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class RunServiceTask : public ThreadPool::Task {
 public:
  virtual void Run() {
    char* error = NULL;
    Isolate* isolate = NULL;

    Dart_IsolateCreateCallback create_callback =
        ServiceIsolate::create_callback();

    Dart_IsolateFlags api_flags;
    Isolate::FlagsInitialize(&amp;amp;api_flags);
    //创建ServiceIsolate [见小节2.3]
    isolate = reinterpret_cast&amp;lt;Isolate*&amp;gt;(
        create_callback(ServiceIsolate::kName, ServiceIsolate::kName, NULL,
                        NULL, &amp;amp;api_flags, NULL, &amp;amp;error));


    bool got_unwind;
    {
      StartIsolateScope start_scope(isolate);
      //[见小节2.4]
      got_unwind = RunMain(isolate);
    }
    ...
    isolate-&amp;gt;message_handler()-&amp;gt;Run(Dart::thread_pool(), NULL, ShutdownIsolate,
                                    reinterpret_cast&amp;lt;uword&amp;gt;(isolate));
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处的create_callback便是DartIsolate::DartIsolateCreateCallback，如下所示。&lt;/p&gt;

&lt;h4 id=&quot;231-dartisolatecreatecallback&quot;&gt;2.3.1 DartIsolateCreateCallback&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/runtime/dart_isolate.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Dart_Isolate DartIsolate::DartIsolateCreateCallback(
    const char* advisory_script_uri,
    const char* advisory_script_entrypoint,
    const char* package_root,
    const char* package_config,
    Dart_IsolateFlags* flags,
    std::shared_ptr&amp;lt;DartIsolate&amp;gt;* parent_embedder_isolate,
    char** error) {
  if (parent_embedder_isolate == nullptr &amp;amp;&amp;amp;
      strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
    return DartCreateAndStartServiceIsolate(package_root,package_config,  
                                            flags, error
    );
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处DART_VM_SERVICE_ISOLATE_NAME就是”vm-service”。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
    const char* package_root,
    const char* package_config,
    Dart_IsolateFlags* flags,
    char** error) {
  auto vm_data = DartVMRef::GetVMData();

  const auto&amp;amp; settings = vm_data-&amp;gt;GetSettings();

  if (!settings.enable_observatory) {
    return nullptr;
  }

  TaskRunners null_task_runners(&quot;io.flutter.&quot; DART_VM_SERVICE_ISOLATE_NAME,
                                nullptr, nullptr, nullptr, nullptr);

  flags-&amp;gt;load_vmservice_library = true;

  std::weak_ptr&amp;lt;DartIsolate&amp;gt; weak_service_isolate =
      DartIsolate::CreateRootIsolate(
          vm_data-&amp;gt;GetSettings(),         // settings
          vm_data-&amp;gt;GetIsolateSnapshot(),  // isolate snapshot
          vm_data-&amp;gt;GetSharedSnapshot(),   // shared snapshot
          null_task_runners,              // task runners
          nullptr,                        // window
          {},                             // snapshot delegate
          {},                             // IO Manager
          DART_VM_SERVICE_ISOLATE_NAME,   // script uri
          DART_VM_SERVICE_ISOLATE_NAME,   // script entrypoint
          flags                           // flags
      );


  tonic::DartState::Scope scope(service_isolate);
  //[见小节2.3.2]
  if (!DartServiceIsolate::Startup(
          settings.ipv6 ? &quot;::1&quot; : &quot;127.0.0.1&quot;,  // server IP address
          settings.observatory_port,            // server observatory port
          tonic::DartState::HandleLibraryTag,   // embedder library tag handler
          false,  //  disable websocket origin check
          settings.disable_service_auth_codes,  // disable VM service auth codes
          error                                 // error (out)
          )) {
    return nullptr;
  }
  ...
  return service_isolate-&amp;gt;isolate();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;可通过settings.enable_observatory来决定是否开启observatory的isolate；&lt;/li&gt;
  &lt;li&gt;启动ip为127.0.0.1的服务；&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;232-dartserviceisolatestartup&quot;&gt;2.3.2 DartServiceIsolate::Startup&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/runtime/dart_service_isolate.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;bool DartServiceIsolate::Startup(std::string server_ip,
                                 intptr_t server_port,
                                 Dart_LibraryTagHandler embedder_tag_handler,
                                 bool disable_origin_check,
                                 bool disable_service_auth_codes,
                                 char** error) {
  Dart_Isolate isolate = Dart_CurrentIsolate();
  ...

  Dart_Handle uri = Dart_NewStringFromCString(&quot;dart:vmservice_io&quot;);
  Dart_Handle library = Dart_LookupLibrary(uri);
  Dart_Handle result = Dart_SetRootLibrary(library);
  result = Dart_SetNativeResolver(library, GetNativeFunction, GetSymbol);

  Dart_ExitScope();
  Dart_ExitIsolate();
  //该过程会执行Isolate::Run()方法
  Dart_IsolateMakeRunnable(isolate);

  Dart_EnterIsolate(isolate);
  Dart_EnterScope();
  library = Dart_RootLibrary();

  //设置HTTP server的ip地址，对于ipv4则为127.0.0.1
  Dart_SetField(library, Dart_NewStringFromCString(&quot;_ip&quot;),
                         Dart_NewStringFromCString(server_ip.c_str()));
  //当指定端口号，则立即启动服务；如果没有指定，则找到第一个可用的端口号
  bool auto_start = server_port &amp;gt;= 0;
  if (server_port &amp;lt; 0) {
    server_port = 0;
  }
  //设置HTTP server的端口号，
  Dart_SetField(library, Dart_NewStringFromCString(&quot;_port&quot;),
                         Dart_NewInteger(server_port));
  Dart_SetField(library, Dart_NewStringFromCString(&quot;_autoStart&quot;),
                         Dart_NewBoolean(auto_start));
  Dart_SetField(library, Dart_NewStringFromCString(&quot;_originCheckDisabled&quot;),
                    Dart_NewBoolean(disable_origin_check));
  Dart_SetField(library, Dart_NewStringFromCString(&quot;_authCodesDisabled&quot;),
                    Dart_NewBoolean(disable_service_auth_codes));
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;设置root library为dart:vmservice_io。&lt;/p&gt;

&lt;h3 id=&quot;24-runmain&quot;&gt;2.4 RunMain&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service_isolate.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;bool RunMain(Isolate* I) {
  Thread* T = Thread::Current();
  StackZone zone(T);
  HANDLESCOPE(T);

  const Library&amp;amp; root_library = Library::Handle(Z, I-&amp;gt;object_store()-&amp;gt;root_library());
  const String&amp;amp; entry_name = String::Handle(Z, String::New(&quot;main&quot;));
  const Function&amp;amp; entry = Function::Handle(
      Z, root_library.LookupFunctionAllowPrivate(entry_name));
  //找到并执行dart:vmservice_io库的main()方法 [见小节2.5]
  const Object&amp;amp; result = Object::Handle(
      Z, DartEntry::InvokeFunction(entry, Object::empty_array()));
  const ReceivePort&amp;amp; rp = ReceivePort::Cast(result);
  ServiceIsolate::SetLoadPort(rp.Id());
  return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;25-vmservice_iomain&quot;&gt;2.5 vmservice_io.main&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/vmservice/vmservice_io.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;main() {
  new VMService();
  if (_autoStart) {
    _lazyServerBoot();  //[见小节2.5.1]
    server.startup();   //[见小节2.6]
    Timer.run(() {});   //用于执行所有的microtasks.
  }
  scriptLoadPort.handler = _processLoadRequest;
  _registerSignalHandlerTimer = new Timer(shortDelay, _registerSignalHandler);
  return scriptLoadPort;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;251-_lazyserverboot&quot;&gt;2.5.1 _lazyServerBoot&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/vmservice/vmservice_io.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;_lazyServerBoot() {
  if (server != null) {
    return;
  }
   //[见小节2.5.2]
  var service = new VMService();
   //[见小节2.5.4]
  server = new Server(service, _ip, _port, _originCheckDisabled, _authCodesDisabled);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该过程创建VMService和Server对象&lt;/p&gt;

&lt;h4 id=&quot;252-vmservice初始化&quot;&gt;2.5.2 VMService初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/vmservice.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;final RawReceivePort isolateControlPort = new RawReceivePort();

class VMService extends MessageRouter {

  factory VMService() {
    if (VMService._instance == null) {
      VMService._instance = new VMService._internal(); //如下文
      _onStart(); //通知虚拟机，服务正在运行
    }
    return _instance;
  }

  VMService._internal() : eventPort = isolateControlPort {
    eventPort.handler = messageHandler; //设置消息处理handler
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;253-messagehandler&quot;&gt;2.5.3 messageHandler&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/vmservice.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;  void messageHandler(message) {
    if (message is List) {
      if (message.length == 2) {
        // 事件处理
        _eventMessageHandler(message[0], new Response.from(message[1]));
        return;
      }
      if (message.length == 1) {
        _exit();  //vm service退出的消息
        return;
      }
      if (message.length == 3) {
        final opcode = message[0];
        if (opcode == Constants.METHOD_CALL_FROM_NATIVE) {
          _handleNativeRpcCall(message[1], message[2]);
          return;
        } else {
          assert((opcode == Constants.WEB_SERVER_CONTROL_MESSAGE_ID) ||
              (opcode == Constants.SERVER_INFO_MESSAGE_ID));
          _serverMessageHandler(message[0], message[1], message[2]);
          return;
        }
      }
      if (message.length == 4) {
        //关于isolate的创建和销毁的消息
        _controlMessageHandler(message[0], message[1], message[2], message[3]);
        return;
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;根据消息长度调用相应的Handler：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;当长度等于1，则调用_exit来退出vm service；&lt;/li&gt;
  &lt;li&gt;当长度等于2，则调用_eventMessageHandler来处理事件；&lt;/li&gt;
  &lt;li&gt;当长度等于3，分为两种情况：
    &lt;ul&gt;
      &lt;li&gt;当消息opcode等于METHOD_CALL_FROM_NATIVE，则调用_handleNativeRpcCall来处理Native的RPC调用；&lt;/li&gt;
      &lt;li&gt;否则，则调用_serverMessageHandler来处理消息；&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;当长度等于4，则调用_controlMessageHandler来通知创建或销毁一个isolate；&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;254-server初始化&quot;&gt;2.5.4 Server初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/vmservice/server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Server {
  static const WEBSOCKET_PATH = '/ws';
  static const ROOT_REDIRECT_PATH = '/index.html';

  final VMService _service;
  final String _ip;
  final int _port;
  final bool _originCheckDisabled;
  final bool _authCodesDisabled;
  HttpServer _server;

  Server(this._service, this._ip, this._port, this._originCheckDisabled,
      bool authCodesDisabled)
      : _authCodesDisabled = (authCodesDisabled || Platform.isFuchsia);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;26-serverstartup&quot;&gt;2.6 server.startup&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/vmservice/server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future startup() async {
  ...
  Future&amp;lt;bool&amp;gt; poll() async {
    try {
      var address;
      var addresses = await InternetAddress.lookup(_ip);
      for (var i = 0; i &amp;lt; addresses.length; i++) {
        address = addresses[i];
        if (address.type == InternetAddressType.IP_V4) break;
      }
      //监听HTTP请求
      _server = await HttpServer.bind(address, _port);
      return true;
    } catch (e, st) {
      return false;
    }
  }

  //轮询尝试，最多10次没有连接成功，则退出
  int attempts = 0;
  final int maxAttempts = 10;
  //尝试跟指定地址和端口建立http请求进行绑定
  while (!await poll()) {
    attempts++;
    if (attempts &amp;gt; maxAttempts) {
      _notifyServerState(&quot;&quot;);
      onServerAddressChange(null);
      return this;
    }
    await new Future&amp;lt;Null&amp;gt;.delayed(const Duration(seconds: 1));
  }
  //进入监听状态
  _server.listen(_requestHandler, cancelOnError: true);
  //这便是熟悉的那行，标志着服务启动成功
  serverPrint('Observatory listening on $serverAddress');

  //将服务地址通知到VmService，写入其成员变量server_uri_
  _notifyServerState(serverAddress.toString());
  //将服务地址通知到ServiceIsolate，写入其成员变量server_address_
  onServerAddressChange('$serverAddress');
  return this;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;服务进入监听状态，一旦收到请求，则会调用_requestHandler。&lt;/p&gt;

&lt;h2 id=&quot;三处理请求&quot;&gt;三、处理请求&lt;/h2&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Server._requestHandler
  client.onRequest
    vmservice.routeRequest
      vmservice._routeRequestImpl
        message.sendToVM
          message.sendRootServiceMessage  (接下来进入C++)
            Service::HandleRootMessage
              Service::InvokeMethod
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;31-server_requesthandler&quot;&gt;3.1 Server._requestHandler&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/vmservice/server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future _requestHandler(HttpRequest request) async {
  ...
  final String path = _checkAuthTokenAndGetPath(request.uri);
  //创建一个client对象，内有vmservice [见小节3.1.1]
  final client = new HttpRequestClient(request, _service);
  //创建message对象，[见小节3.1.3]
  final message = new Message.fromUri(client, Uri.parse(path));
  // [见小节3.2]
  client.onRequest(message);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;311-httprequestclient初始化&quot;&gt;3.1.1 HttpRequestClient初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/vmservice/server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class HttpRequestClient extends Client {
  final HttpRequest request;

  HttpRequestClient(this.request, VMService service)
      : super(service, sendEvents: false); //见下文
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/client.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;abstract class Client {
  final VMService service;
  final bool sendEvents;

  Client(this.service, {bool sendEvents: true}) : this.sendEvents = sendEvents {
    service._addClient(this);  //将当前的client添加到VMService
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;312-vmservice_addclient&quot;&gt;3.1.2 VMService._addClient&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/vmservice.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class VMService extends MessageRouter {
  static const serviceNamespace = 's';

  final NamedLookup&amp;lt;Client&amp;gt; clients =
      new NamedLookup&amp;lt;Client&amp;gt;(prologue: serviceNamespace);

  void _addClient(Client client) {
    clients.add(client);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;313-messagefromuri&quot;&gt;3.1.3 Message.fromUri&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/message.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Message.fromUri(this.client, Uri uri)
    : type = MessageType.Request,
      serial = '',
      method = _methodNameFromUri(uri) { //从uri中获取方法名
  params.addAll(uri.queryParameters);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Message对象都有一个成员变量method&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;方法名method，对于fromUri是从分割后的第一部分&lt;/li&gt;
  &lt;li&gt;消息类型type有有3大类：Request, Notification, Response&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;32-clientonrequest&quot;&gt;3.2 client.onRequest&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/client.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;abstract class Client {
  final VMService service;

  void onRequest(Message message) {
    // 【见小节3.3/38】
    service.routeRequest(service, message).then(post);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里有两个过程：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;vmservice.routeRequest&lt;/li&gt;
  &lt;li&gt;post&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;33-vmservicerouterequest&quot;&gt;3.3 vmservice.routeRequest&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/vmservice.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;Response&amp;gt; routeRequest(VMService _, Message message) async {
  return new Response.from(await _routeRequestImpl(message));
}

Future _routeRequestImpl(Message message) async {
  try {
    if (message.completed) {
      return await message.response;
    }
    if (message.method == 'streamListen') {
      return await _streamListen(message);
    }
    if (message.method == 'streamCancel') {
      return await _streamCancel(message);
    }
    if (message.method == '_registerService') {
      return await _registerService(message);
    }
    if (message.method == '_spawnUri') {
      return await _spawnUri(message);
    }
    if (devfs.shouldHandleMessage(message)) {
      return await devfs.handleMessage(message);
    }
    if (_hasNamespace(message.method)) {
      return await _handleService(message);
    }
    if (message.params['isolateId'] != null) {
      return await runningIsolates.routeRequest(this, message);
    }
    return await message.sendToVM(); //[见小节3.4]
  } catch (e, st) {
    return message.response;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;34-messagesendtovm&quot;&gt;3.4 message.sendToVM&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/vmservice/message.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;Response&amp;gt; sendToVM() {
  final receivePort = new RawReceivePort();
  receivePort.handler = (value) {
    receivePort.close();
    _setResponseFromPort(value);
  };
  var keys = params.keys.toList(growable: false);
  var values = params.values.toList(growable: false);
  if (!_methodNeedsObjectParameters(method)) {
    keys = _makeAllString(keys);
    values = _makeAllString(values);
  }

  final request = new List(6)
    ..[0] = 0
    ..[1] = receivePort.sendPort
    ..[2] = serial
    ..[3] = method
    ..[4] = keys
    ..[5] = values;

  if (_methodNeedsObjectParameters(method)) {
    sendObjectRootServiceMessage(request);  //[见小节3.5]
  } else {
    sendRootServiceMessage(request);  //[见小节3.5]
  }

  return _completer.future;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;sendRootServiceMessage，这是一个native方法，调用到vmservice.cc中相应的方法&lt;/p&gt;

&lt;h3 id=&quot;35-messagesendrootservicemessage&quot;&gt;3.5 message.sendRootServiceMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/lib/vmservice.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DEFINE_NATIVE_ENTRY(VMService_SendRootServiceMessage, 0, 1) {
#ifndef PRODUCT
  GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments-&amp;gt;NativeArgAt(0));
  if (FLAG_support_service) {
    return Service::HandleRootMessage(message);  //[见小节3.6]
  }
#endif
  return Object::null();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DEFINE_NATIVE_ENTRY(VMService_SendObjectRootServiceMessage, 0, 1) {
#ifndef PRODUCT
  GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments-&amp;gt;NativeArgAt(0));
  if (FLAG_support_service) {
    return Service::HandleObjectRootMessage(message);
  }
#endif
  return Object::null();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;36-servicehandlerootmessage&quot;&gt;3.6 Service::HandleRootMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;RawError* Service::HandleRootMessage(const Array&amp;amp; msg_instance) {
  Isolate* isolate = Isolate::Current();
  return InvokeMethod(isolate, msg_instance);  //[见小节3.7]
}

RawError* Service::HandleObjectRootMessage(const Array&amp;amp; msg_instance) {
  Isolate* isolate = Isolate::Current();
  return InvokeMethod(isolate, msg_instance, true);  //[见小节3.7]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;37-serviceinvokemethod&quot;&gt;3.7 Service::InvokeMethod&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;RawError* Service::InvokeMethod(Isolate* I, const Array&amp;amp; msg,
                                bool parameters_are_dart_objects) {
  Thread* T = Thread::Current();
  {
    StackZone zone(T);
    HANDLESCOPE(T);
    Instance&amp;amp; reply_port = Instance::Handle(Z);
    Instance&amp;amp; seq = String::Handle(Z);
    String&amp;amp; method_name = String::Handle(Z);
    Array&amp;amp; param_keys = Array::Handle(Z);
    Array&amp;amp; param_values = Array::Handle(Z);
    reply_port ^= msg.At(1);
    seq ^= msg.At(2);
    method_name ^= msg.At(3);
    param_keys ^= msg.At(4);
    param_values ^= msg.At(5);

    JSONStream js;
    Dart_Port reply_port_id =
        (reply_port.IsNull() ? ILLEGAL_PORT : SendPort::Cast(reply_port).Id());
    js.Setup(zone.GetZone(), reply_port_id, seq, method_name, param_keys,
             param_values, parameters_are_dart_objects);
    ...
    const char* c_method_name = method_name.ToCString();
    //从service_methods_[]找到目标方法 [3.7.1]
    const ServiceMethodDescriptor* method = FindMethod(c_method_name);
    if (method != NULL) {
      if (method-&amp;gt;entry(T, &amp;amp;js)) {  //执行相应方法
        js.PostReply();
      }
      return T-&amp;gt;StealStickyError();
    }
    ...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;371-findmethod&quot;&gt;3.7.1 FindMethod&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/service.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;const ServiceMethodDescriptor* FindMethod(const char* method_name) {
  intptr_t num_methods = sizeof(service_methods_) / sizeof(service_methods_[0]);
  for (intptr_t i = 0; i &amp;lt; num_methods; i++) {
    const ServiceMethodDescriptor&amp;amp; method = service_methods_[i];
    if (strcmp(method_name, method.name) == 0) {
      return &amp;amp;method;
    }
  }
  return NULL;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在service.cc中有一个成员变量service_methods_[]记录了所有的定义的方法。比如获取timeline的过程，如下所示。&lt;/p&gt;

&lt;h4 id=&quot;372-service_methods_数组&quot;&gt;3.7.2 service_methods_数组&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;struct ServiceMethodDescriptor {
  const char* name;
  const ServiceMethodEntry entry;
  const MethodParameter* const* parameters;
};

static const ServiceMethodDescriptor service_methods_[] = {
  { &quot;_echo&quot;, Echo,
    NULL },
  { &quot;_respondWithMalformedJson&quot;, RespondWithMalformedJson,
    NULL },
  { &quot;_respondWithMalformedObject&quot;, RespondWithMalformedObject,
    NULL },
  { &quot;_triggerEchoEvent&quot;, TriggerEchoEvent,
    NULL },
  { &quot;addBreakpoint&quot;, AddBreakpoint,
    add_breakpoint_params },
  { &quot;addBreakpointWithScriptUri&quot;, AddBreakpointWithScriptUri,
    add_breakpoint_with_script_uri_params },
  { &quot;addBreakpointAtEntry&quot;, AddBreakpointAtEntry,
    add_breakpoint_at_entry_params },
  { &quot;_addBreakpointAtActivation&quot;, AddBreakpointAtActivation,
    add_breakpoint_at_activation_params },
  { &quot;_buildExpressionEvaluationScope&quot;, BuildExpressionEvaluationScope,
    build_expression_evaluation_scope_params },
  { &quot;_clearCpuProfile&quot;, ClearCpuProfile,
    clear_cpu_profile_params },
  { &quot;_clearVMTimeline&quot;, ClearVMTimeline,
    clear_vm_timeline_params, },
  { &quot;_compileExpression&quot;, CompileExpression, compile_expression_params },
  { &quot;_enableProfiler&quot;, EnableProfiler,
    enable_profiler_params, },
  { &quot;evaluate&quot;, Evaluate,
    evaluate_params },
  { &quot;evaluateInFrame&quot;, EvaluateInFrame,
    evaluate_in_frame_params },
  { &quot;_getAllocationProfile&quot;, GetAllocationProfile,
    get_allocation_profile_params },
  { &quot;_getAllocationSamples&quot;, GetAllocationSamples,
      get_allocation_samples_params },
  { &quot;_getNativeAllocationSamples&quot;, GetNativeAllocationSamples,
      get_native_allocation_samples_params },
  { &quot;getClassList&quot;, GetClassList,
    get_class_list_params },
  { &quot;_getCpuProfile&quot;, GetCpuProfile,
    get_cpu_profile_params },
  { &quot;_getCpuProfileTimeline&quot;, GetCpuProfileTimeline,
    get_cpu_profile_timeline_params },
  { &quot;_writeCpuProfileTimeline&quot;, WriteCpuProfileTimeline,
    write_cpu_profile_timeline_params },
  { &quot;getFlagList&quot;, GetFlagList,
    get_flag_list_params },
  { &quot;_getHeapMap&quot;, GetHeapMap,
    get_heap_map_params },
  { &quot;_getInboundReferences&quot;, GetInboundReferences,
    get_inbound_references_params },
  { &quot;_getInstances&quot;, GetInstances,
    get_instances_params },
  { &quot;getIsolate&quot;, GetIsolate,
    get_isolate_params },
  { &quot;getMemoryUsage&quot;, GetMemoryUsage,
    get_memory_usage_params },
  { &quot;_getIsolateMetric&quot;, GetIsolateMetric,
    get_isolate_metric_params },
  { &quot;_getIsolateMetricList&quot;, GetIsolateMetricList,
    get_isolate_metric_list_params },
  { &quot;getObject&quot;, GetObject,
    get_object_params },
  { &quot;_getObjectStore&quot;, GetObjectStore,
    get_object_store_params },
  { &quot;_getObjectByAddress&quot;, GetObjectByAddress,
    get_object_by_address_params },
  { &quot;_getPersistentHandles&quot;, GetPersistentHandles,
      get_persistent_handles_params, },
  { &quot;_getPorts&quot;, GetPorts,
    get_ports_params },
  { &quot;_getReachableSize&quot;, GetReachableSize,
    get_reachable_size_params },
  { &quot;_getRetainedSize&quot;, GetRetainedSize,
    get_retained_size_params },
  { &quot;_getRetainingPath&quot;, GetRetainingPath,
    get_retaining_path_params },
  { &quot;getScripts&quot;, GetScripts,
    get_scripts_params },
  { &quot;getSourceReport&quot;, GetSourceReport,
    get_source_report_params },
  { &quot;getStack&quot;, GetStack,
    get_stack_params },
  { &quot;_getUnusedChangesInLastReload&quot;, GetUnusedChangesInLastReload,
    get_unused_changes_in_last_reload_params },
  { &quot;_getTagProfile&quot;, GetTagProfile,
    get_tag_profile_params },
  { &quot;_getTypeArgumentsList&quot;, GetTypeArgumentsList,
    get_type_arguments_list_params },
  { &quot;getVersion&quot;, GetVersion,
    get_version_params },
  { &quot;getVM&quot;, GetVM,
    get_vm_params },
  { &quot;_getVMMetric&quot;, GetVMMetric,
    get_vm_metric_params },
  { &quot;_getVMMetricList&quot;, GetVMMetricList,
    get_vm_metric_list_params },
  { &quot;_getVMTimeline&quot;, GetVMTimeline,
    get_vm_timeline_params },
  { &quot;_getVMTimelineFlags&quot;, GetVMTimelineFlags,
    get_vm_timeline_flags_params },
  { &quot;invoke&quot;, Invoke, invoke_params },
  { &quot;kill&quot;, Kill, kill_params },
  { &quot;pause&quot;, Pause,
    pause_params },
  { &quot;removeBreakpoint&quot;, RemoveBreakpoint,
    remove_breakpoint_params },
  { &quot;reloadSources&quot;, ReloadSources,
    reload_sources_params },
  { &quot;_reloadSources&quot;, ReloadSources,
    reload_sources_params },
  { &quot;resume&quot;, Resume,
    resume_params },
  { &quot;_requestHeapSnapshot&quot;, RequestHeapSnapshot,
    request_heap_snapshot_params },
  { &quot;_evaluateCompiledExpression&quot;, EvaluateCompiledExpression,
    evaluate_compiled_expression_params },
  { &quot;setExceptionPauseMode&quot;, SetExceptionPauseMode,
    set_exception_pause_mode_params },
  { &quot;setFlag&quot;, SetFlag,
    set_flags_params },
  { &quot;setLibraryDebuggable&quot;, SetLibraryDebuggable,
    set_library_debuggable_params },
  { &quot;setName&quot;, SetName,
    set_name_params },
  { &quot;_setTraceClassAllocation&quot;, SetTraceClassAllocation,
    set_trace_class_allocation_params },
  { &quot;setVMName&quot;, SetVMName,
    set_vm_name_params },
  { &quot;_setVMTimelineFlags&quot;, SetVMTimelineFlags,
    set_vm_timeline_flags_params },
  { &quot;_collectAllGarbage&quot;, CollectAllGarbage,
    collect_all_garbage_params },
  { &quot;_getDefaultClassesAliases&quot;, GetDefaultClassesAliases,
    get_default_classes_aliases_params },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;38-httprequestclient&quot;&gt;3.8 HttpRequestClient&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class HttpRequestClient extends Client {
  static ContentType jsonContentType =
      new ContentType(&quot;application&quot;, &quot;json&quot;, charset: &quot;utf-8&quot;);
  final HttpRequest request;


  void post(Response result) {
    HttpResponse response = request.response;
    response.headers.add('Access-Control-Allow-Origin', '*');
    response.headers.contentType = jsonContentType;
    switch (result.kind) {
      case ResponsePayloadKind.String:
        response.write(result.payload);
        break;
      case ResponsePayloadKind.Utf8String:
        response.add(result.payload);
        break;
      case ResponsePayloadKind.Binary:
        throw 'Can not handle binary responses';
    }
    response.close();
    close();
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;四小结&quot;&gt;四、小结&lt;/h2&gt;

&lt;p&gt;ServiceIsolate处理监听状态，根据具体的命令，最终会执行执行到service.cc的成service_methods_数组中所定义的方法。看到这里，你可能还不了解其功能。
这只是为下一篇文章介绍timeline工作原理做铺垫而已。&lt;/p&gt;
</description>
        <pubDate>Sat, 12 Oct 2019 22:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/10/12/service-isolate/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/10/12/service-isolate/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>Dart虚拟机运行原理</title>
        <description>&lt;h2 id=&quot;一dart虚拟机&quot;&gt;一、Dart虚拟机&lt;/h2&gt;

&lt;h4 id=&quot;11-引言&quot;&gt;1.1 引言&lt;/h4&gt;
&lt;p&gt;Dart VM是一种虚拟机，为高级编程语言Dart提供执行环境，但这并意味着Dart在D虚拟机上执行时，总是采用解释执行或者JIT编译。
例如还可以使用Dart虚拟机的AOT管道将Dart代码编译为机器代码，然后运行在Dart虚拟机的精简版环境，称之为预编译运行时(precompiled runtime)环境，该环境不包含任何编译器组件，且无法动态加载Dart源代码。&lt;/p&gt;

&lt;h4 id=&quot;12-虚拟机如何运行dart代码&quot;&gt;1.2 虚拟机如何运行Dart代码&lt;/h4&gt;

&lt;p&gt;Dart VM有多钟方式来执行代码：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;源码或者Kernel二进制(JIT)&lt;/li&gt;
  &lt;li&gt;snapshot
    &lt;ul&gt;
      &lt;li&gt;AOT snapshot&lt;/li&gt;
      &lt;li&gt;AppJIT snapshot&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;区别主要在于什么时机以及如何将Dart代码转换为可执行的代码。&lt;/p&gt;

&lt;h4 id=&quot;13-isolate组成&quot;&gt;1.3 Isolate组成&lt;/h4&gt;

&lt;p&gt;先来看看dart虚拟机中isolate的组成：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/isolates.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;isolate堆是运该isolate中代码分配的所有对象的GC管理的内存存储；&lt;/li&gt;
  &lt;li&gt;vm isolate是一个伪isolate，里面包含不可变对象，比如null，true，false；&lt;/li&gt;
  &lt;li&gt;isolate堆能引用vm isolate堆中的对象，但vm isolate不能引用isolate堆；&lt;/li&gt;
  &lt;li&gt;isolate彼此之间不能相互引用&lt;/li&gt;
  &lt;li&gt;每个isolate都有一个执行dart代码的Mutator thread，一个处理虚拟机内部任务(比如GC, JIT等)的helper thread；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;isolate拥有内存堆和控制线程，虚拟机中可以有很多isolate，但彼此之间不能直接状态，只能通过dart特有的端口；isolate除了拥有一个mutator控制线程，还有一些其他辅助线程：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;后台JIT编译线程；&lt;/li&gt;
  &lt;li&gt;GC清理线程；&lt;/li&gt;
  &lt;li&gt;GC并发标记线程；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;线程和isolate的关系是什么呢？&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;同一个线程在同一时间只能进入一个isolate，当需要进入另一个isolate则必须先退出当前的isolate；&lt;/li&gt;
  &lt;li&gt;一次只能有一个Mutator线程关联对应的isolate，Mutator线程是执行Dart代码并使用虚拟机的公共的C语言API的线程&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;14-threadpool组成&quot;&gt;1.4 ThreadPool组成&lt;/h4&gt;
&lt;p&gt;虚拟机采用线程池的方式来管理线程，定义在runtime/vm/thread_pool.h&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/ThreadPool.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;ThreadPool的核心成员变量：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;all_workers_：记录所有的workers；&lt;/li&gt;
  &lt;li&gt;idle_workers：_记录所有空闲的workers;&lt;/li&gt;
  &lt;li&gt;count_started_：记录该线程池的历史累计启动workers个数;&lt;/li&gt;
  &lt;li&gt;count_stopped_：记录该线程池的历史累计关闭workers个数；&lt;/li&gt;
  &lt;li&gt;count_running_：记录该线程池当前正在运行的worker个数；&lt;/li&gt;
  &lt;li&gt;count_idle_：记录该线程池当前处于空闲的worker个数，也就是idle_workers的长度；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ThreadPool核心方法：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Run(Task*): 执行count_running_加1，并将Task设置到该Worker，
    &lt;ul&gt;
      &lt;li&gt;当idle_workers_为空，则创建新的Worker并添加到all_workers_队列头部，count_started_加1；&lt;/li&gt;
      &lt;li&gt;当idle_workers_不为空，则取走idle_workers_队列头部的Worker，count_idle_减1；&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Shutdown(): 将all_workers_和idle_workers_队列置为NULL，并将count_running_和count_idle_清零，将关闭的all_workers_个数累加到count_stopped_；&lt;/li&gt;
  &lt;li&gt;SetIdleLocked(Worker*)：将该Worker添加到idle_workers_队列头部，count_idle_加1， count_running_减1;&lt;/li&gt;
  &lt;li&gt;ReleaseIdleWorker(Worker*)：从all_workers_和idle_workers_队列中移除该Worker，count_idle_减1，count_stopped_加1；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;对应关系图：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;count_started_&lt;/th&gt;
      &lt;th&gt;count_stopped_&lt;/th&gt;
      &lt;th&gt;count_running_&lt;/th&gt;
      &lt;th&gt;count_idle_&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Run()&lt;/td&gt;
      &lt;td&gt;+1(无空闲worker)&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;+1&lt;/td&gt;
      &lt;td&gt;-1(有空闲worker)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Shutdown()&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;+all_workers_个数&lt;/td&gt;
      &lt;td&gt;清零&lt;/td&gt;
      &lt;td&gt;清零&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;SetIdleLocked()&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;-1&lt;/td&gt;
      &lt;td&gt;+1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ReleaseIdleWorker()&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;+1&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;-1&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;可见，count_started_ - count_stopped_ = count_running_ + count_idle_；&lt;/p&gt;

&lt;h2 id=&quot;二jit运行模式&quot;&gt;二、JIT运行模式&lt;/h2&gt;

&lt;h4 id=&quot;21-cfe前端编译器&quot;&gt;2.1 CFE前端编译器&lt;/h4&gt;

&lt;p&gt;看看dart是如何直接理解并执行dart源码&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// gityuan.dart
main() =&amp;gt; print('Hello Gityuan!');

//dart位于flutter/bin/cache/dart-sdk/bin/dart
$ dart gityuan.dart
Hello, World!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dart虚拟机并不能直接从Dart源码执行，而是执行dill二进制文件，该二进制文件包括序列化的Kernel AST(抽象语法树)。&lt;/li&gt;
  &lt;li&gt;Dart Kernel是一种从Dart中衍生而来的高级语言，设计之初用于程序分析与转换(transformations)的中间产物，可用于代码生成与后端编译器，该kernel语言有一个内存表示，可以序列化为二进制或文本。&lt;/li&gt;
  &lt;li&gt;将Dart转换为Kernel AST的是CFE(common front-end）通用前端编译器。&lt;/li&gt;
  &lt;li&gt;生成的Kernel AST可交由Dart VM、dev_compiler以及dart2js等各种Dart工具直接使用。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/dart-to-kernel.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;22-kernel-service&quot;&gt;2.2 kernel service&lt;/h4&gt;
&lt;p&gt;有一个辅助类isolate叫作kernel service，其核心工作就是CFE，将dart转为Kernel二进制，然后VM可直接使用Kernel二进制运行在主isolate里面运行。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/kernel-service.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;23-debug运行&quot;&gt;2.3 debug运行&lt;/h4&gt;
&lt;p&gt;将dart代码转换为kernel二进制和执行kernel二进制，这两个过程也可以分离开来，在两个不同的机器执行，比如host机器执行编译，移动设备执行kernel文件。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/flutter-cfe.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;图解：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;这个编译过程并不是flutter tools自身完成，而是交给另一个进程frontend_server来执行，它包括CFE和一些flutter专有的kernel转换器。&lt;/li&gt;
  &lt;li&gt;hot reload：热重载机制正是依赖这一点，frontend_server重用上一次编译中的CFE状态，只重新编译实际更改的部分。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;24-rawclass内部结构&quot;&gt;2.4 RawClass内部结构&lt;/h4&gt;
&lt;p&gt;虚拟机内部对象的命名约定：使用C++定义的，其名称在头文件raw_object.h中以Raw开头，比如RawClass是描述Dart类的VM对象，RawField是描述Dart类中的Dart字段的VM对象。&lt;/p&gt;

&lt;p&gt;1）将内核二进制文件加载到VM后，将对其进行解析以创建表示各种程序实体的对象。这里采用了懒加载模式，一开始只有库和类的基本信息被加载，内核二进制文件中的每一个实体都会保留指向该二进制文件的指针，以便后续可根据需要加载更多信息。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/kernel-loaded-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;2）仅在以后需要运行时，才完全反序列化有关类的信息。（例如查找类的成员变量，创建类的实例对象等），便会从内核二进制文件中读取类的成员信息。
但功能完整的主体(FunctionNode)在此阶段并不会反序列化，而只是获取其签名。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/kernel-loaded-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;到此，已从内核二进制文件加载了足够的信息以供运行时成功解析和调用的方法。&lt;/p&gt;

&lt;p&gt;所有函数的主体都具有占位符code_，而不是实际的可执行代码：它们指向LazyCompileStub，该Stub只是简单地要求系统Runtime为当前函数生成可执行代码，然后对这些新生成的代码进行尾部调用。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/raw-function-lazy-compile.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;25-查看kernel文件格式&quot;&gt;2.5 查看Kernel文件格式&lt;/h4&gt;

&lt;p&gt;gen_kernel.dart利用CFE将Dart源码编译为kernel binary文件(也就是dill)，可利用dump_kernel.dart能反解kernel binary文件，命令如下所示：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;//将hello.dart编译成hello.dill
$ cd &amp;lt;FLUTTER_ENGINE_ROOT&amp;gt;
$ dart third_party/dart/pkg/vm/bin/gen_kernel.dart          \
       --platform out/android_debug/vm_platform_strong.dill \
       -o hello.dill                                        \
       hello.dart

//转储AST的文本表示形式
$ dart third_party/dart/pkg/vm/bin/dump_kernel.dart hello.dill hello.kernel.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;gen_kernel.dart文件，需要平台dill文件，这是一个包括所有核心库(dart:core, dart:async等)的AST的kernel binary文件。如果Dart SDK已经编译过，可直接使用out/ReleaseX64/vm_platform_strong.dill，否则需要使用compile_platform.dart来生成平台dill文件，如下命令:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;//根据给定的库列表，来生成platform和outline文件
$ cd &amp;lt;FLUTTER_ENGINE_ROOT&amp;gt;
$ dart third_party/dart/pkg/front_end/tool/_fasta/compile_platform.dart \
       dart:core                                                        \        
       third_party/dart/sdk/lib/libraries.json                          \
       vm_outline.dill vm_platform.dill vm_outline.dill                 
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;26-未优化编译器&quot;&gt;2.6 未优化编译器&lt;/h4&gt;
&lt;p&gt;首次编译函数时，这是通过未优化编译器来完成的。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/unoptimized-compilation.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;未优化的编译器分两步生成机器代码：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AST -&amp;gt; CFG: 对函数主体的序列化AST进行遍历，以生成函数主体的控制流程图(CFG)，CFG是由填充中间语言（IL）指令的基本块组成。此阶段使用的IL指令类似于基于堆栈的虚拟机的指令：它们从堆栈中获取操作数，执行操作，然后将结果压入同一堆栈&lt;/li&gt;
  &lt;li&gt;IL -&amp;gt; 机器指令：使用一对多的IL指令，将生成的CFG直接编译为机器代码：每个IL指令扩展为多条机器指令。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在此阶段没有执行优化，未优化编译器的主要目标是快速生成可执行代码。&lt;/p&gt;

&lt;h4 id=&quot;27-内联缓存&quot;&gt;2.7 内联缓存&lt;/h4&gt;

&lt;p&gt;未优化编译过程，编译器不会尝试静态解析任何未在Kernel二进制文件中解析的调用，因此（MethodInvocation或PropertyGet AST节点）的调用被编译为完全动态的。虚拟机当前不使用任何形式的基于虚拟表(virtual table)或接口表(interface table)的调度，而是使用内联缓存实现动态调用。&lt;/p&gt;

&lt;p&gt;虚拟机的内联缓存的核心思想是缓存方法解析后的站点结果信息，对于内联缓存最初是为了解决函数的本地代码：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;站点调用的特定缓存(RawICData对象)将接受者的类映射到方法，缓存中记录着一些辅助信息，比如方法和基本块的调用频次计数器，该计数器记录着被跟踪类的调用频次；&lt;/li&gt;
  &lt;li&gt;共享的查找存根，用于实现方法调用的快速路径。该存根在给定的高速缓存中进行搜索，以查看其是否包含与接收者的类别匹配的条目。
如果找到该条目，则存根将增加频率计数器和尾部调用缓存的方法。否则，存根将调用系统Runtime来解析方法实现的逻辑，如果方法解析成功，则将更新缓存，并且随后的调用无需进入系统Runtime。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/inline-cache-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;28-编译优化&quot;&gt;2.8 编译优化&lt;/h4&gt;
&lt;p&gt;未优化编译器产生的代码执行比较慢，需要自适应优化，通过profile配置文件来驱动优化策略。内联优化，当与某个功能关联的执行计数器达到某个阈值时，该功能将提交给后台优化编译器进行优化。&lt;/p&gt;

&lt;p&gt;优化编译的方式与未优化编译的方式相同：通过序列化内核AST来构建未优化的IL。但是，优化编译器不是直接将IL编译为机器码，而是将未优化的IL转换为基于静态单分配（SSA）形式的优化的IL。&lt;/p&gt;

&lt;p&gt;对基于SSA的IL通过基于收集到的类型反馈，内联，范围分析，类型传播，表示选择，存储到加载，加载到加载转发，全局值编号，分配接收等一系列经典和Dart特定的优化来进行专业化推测。最后，使用线性扫描寄存器分配器和一个简单的一对多的IL指令。优化编译完成后，后台编译器会请求mutator线程输入安全点，并将优化的代码附加到该函数。下次调用该函数时，它将使用优化的代码。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/optimizing-compilation.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;另外，有些函数包含很长的运行循环，因此在函数仍在运行时将执行从未优化的代码切换到优化的代码是有意义的，此过程之所以称为“堆栈替换”（OSR）。&lt;/p&gt;

&lt;p&gt;VM还具有可用于控制JIT并使其转储IL以及用于JIT正在编译的功能的机器代码的标志&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;$ dart --print-flow-graph-optimized         \
       --disassemble-optimized              \
       --print-flow-graph-filter=myFunc     \
       --no-background-compilation          \
       hel.dart
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;29-反优化&quot;&gt;2.9 反优化&lt;/h4&gt;
&lt;p&gt;优化是基于统计的，可能出现违反优化的情况&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void printAnimal(obj) {
  print('Animal {');
  print('  ${obj.toString()}');
  print('}');
}

// 大量调用的情况下，会推测printAnimal假设总是Cat的情况下来优化代码
for (var i = 0; i &amp;lt; 50000; i++)
  printAnimal(Cat());

// 此处出现的是Dog，优化版本失效，则触发反优化
printAnimal(Dog());
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;每当只要优化版本遇到无法解决的情况，它就会将执行转移到未优化功能的匹配点，然后继续执行，这个恢复过程称为去优化：未优化的功能版本不做任何假设，可以处理所有可能的输入。&lt;/p&gt;

&lt;p&gt;虚拟机通常会在执行一次反优化后，放弃该功能的优化版本，然后在以后使用优化的类型反馈再次对其进行重新优化。虚拟机保护编译器进行推测性假设的方式有两种：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;内联检查（例如CheckSmi，CheckClass IL指令），以验证假设是否在编译器做出此假设的使用场所成立。例如，将动态调用转换为直接调用时，编译器会在直接调用之前添加这些检查。
在此类检查中发生的取消优化称为“急切优化”，因为它在达到检查时就急于发生。&lt;/li&gt;
  &lt;li&gt;运行时在更改优化代码所依赖的内容时，将会丢弃优化代码。例如，优化编译器可能会发现某些类从未扩展过，并且在类型传播过程中使用了此信息。
但是，随后的动态代码加载或类最终确定可能会引入C的子类，导致假设无效。此时，运行时需要查找并丢弃所有在C没有子类的假设下编译的优化代码。
运行时可能会在执行堆栈上找到一些现在无效的优化代码，在这种情况下，受影响的帧将被标记为不优化，并且当执行返回时将进行不优化。
这种取消优化称为延迟取消优化，因为它会延迟到控制权返回到优化代码为止。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;三snapshots运行模式&quot;&gt;三、Snapshots运行模式&lt;/h2&gt;

&lt;h3 id=&quot;31-通过snapshots运行&quot;&gt;3.1 通过Snapshots运行&lt;/h3&gt;

&lt;p&gt;1）虚拟机有能力将isolate的堆（驻留在堆上的对象图）序列化成二进制的快照，启动虚拟机isolate的时候可以从快照中重新创建相同的状态。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/snapshot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Snapshot的格式是低级的，并且针对快速启动进行了优化，本质上是要创建的对象列表以及如何将它们连接在一起的说明。那是快照背后的原始思想：代替解析Dart源码并逐步创建虚拟机内部的数据结构，这样虚拟机通过快照中的所有必要数据结构来快速启动isolate。&lt;/p&gt;

&lt;p&gt;2）最初，快照不包括机器代码，但是后来在开发AOT编译器时添加了此功能。开发AOT编译器和带代码快照的动机是为了允许虚拟机在由于平台级别限制而无法进行JIT的平台上使用。&lt;/p&gt;

&lt;p&gt;带代码的快照的工作方式几乎与普通快照相同，只是有一点点不同：它们包括一个代码部分，该部分与快照的其余部分不同，不需要反序列化。该代码节的放置方式使其可以在映射到内存后直接成为堆的一部分&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/snapshot-with-code.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;32-通过appjit-snapshots运行&quot;&gt;3.2 通过AppJIT Snapshots运行&lt;/h3&gt;

&lt;p&gt;引入AppJIT快照可减少大型Dart应用程序（如dartanalyzer或dart2js）的JIT预热时间。当这些工具用于小型项目时，它们花费的实际时间与VM花费的JIT编译这些应用程序的时间一样多。&lt;/p&gt;

&lt;p&gt;AppJIT快照可以解决此问题：可以使用一些模拟训练数据在VM上运行应用程序，然后将所有生成的代码和VM内部数据结构序列化为AppJIT快照。然后可以分发此快照，而不是以源（或内核二进制）形式分发应用程序。如果出现实际数据上的执行配置文件与培训期间观察到的执行配置文件不匹配，快照开始的VM仍可以采用JIT模式执行。&lt;/p&gt;

&lt;h3 id=&quot;33-通过appaot-snapshots运行&quot;&gt;3.3 通过AppAOT Snapshots运行&lt;/h3&gt;
&lt;p&gt;AOT快照最初是为无法进行JIT编译的平台引入的，对于无法进行JIT意味着：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AOT快照必须包含应用程序执行期间可能调用的每个功能的可执行代码;&lt;/li&gt;
  &lt;li&gt;可执行代码不得依赖于执行期间可能违反的任何推测性假设&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;为了满足这些要求，AOT编译过程会进行全局静态分析（类型流分析, TFA），以确定从已知入口点集中可访问应用程序的哪些部分，分配了哪些类的实例以及类型如何在程序中流动。
所有这些分析都是保守的：这意味着它们会在正确性方面出错，与可以在性能方面出错的JIT形成鲜明对比，因为它始终可以取消优化为未优化的代码以实现正确的行为。&lt;/p&gt;

&lt;p&gt;然后，所有可能达到的功能都将编译为本地代码，而无需进行任何推测性优化。但是，类型流信息仍用于专门化代码（例如，取消虚拟化调用），编译完所有函数后，即可获取堆的快照。&lt;/p&gt;

&lt;p&gt;最终的快照snapshot可以运行在预编译Runtime，该Runtime是Dart VM的特殊变体，其中不包括诸如JIT和动态代码加载工具之类的组件。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/aot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;AOT编译工具没有包含进Dart SDK。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;//需要构建正常的dart可执行文件和运行AOT代码的runtime
$ tool/build.py -m release -a x64 runtime dart_precompiled_runtime

// 使用AOT编译器来编译APP
$ pkg/vm/tool/precompiler2 hello.dart hello.aot

//执行AOT快照
$ out/ReleaseX64/dart_precompiled_runtime hello.aot
Hello, World!
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;331-switchable-calls&quot;&gt;3.3.1 Switchable Calls&lt;/h4&gt;

&lt;p&gt;1）即使进行了全局和局部分析，AOT编译的代码仍可能包含无法静态的去虚拟化的调用站点。为了补偿此AOT编译代码和运行时，采用JIT中使用的内联缓存技术的扩展。此扩展版本称为可切换呼叫 （Switchable Calls）。&lt;/p&gt;

&lt;p&gt;JIT部分已经描述过，与调用站点关联的每个内联缓存均由两部分组成：一个缓存对象（由RawICData实例表示）和一个要调用的本机代码块（例如InlineCacheStub）。在JIT模式下，运行时只会更新缓存本身。但在AOT运行时中，可以根据内联缓存的状态选择同时替换缓存和要调用的本机代码。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/aot-ic-unlinked.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;最初，所有动态呼叫均以未链接状态开始。首次调用此类呼叫站点时，将调用UnlinkedCallStub，它只是调用运行时帮助程序DRT_UnlinkedCall来链接此呼叫站点。&lt;/p&gt;

&lt;p&gt;2）如果可能，DRT_UnlinkedCall尝试将呼叫站点转换为单态状态。在这种状态下，呼叫站点变成直接呼叫，该呼叫通过特殊的单态入口点进入方法，该入口点验证接收方是否具有预期的类。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/aot-ic-monomorphic.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;在上面的示例中，假设第一次执行obj.method（）时，obj是C的实例，而obj.method则解析为C.method。&lt;/p&gt;

&lt;p&gt;下次执行相同的调用站点时，它将直接调用C.method，从而绕过任何类型的方法查找过程。但是，它将通过特殊的入口点(已验证obj仍然是C的实例)进入C.method。如果不是这种情况，将调用DRT_MonomorphicMiss并将尝试选择下一个调用站点状态。&lt;/p&gt;

&lt;p&gt;3）C.method可能仍然是调用的有效目标，例如obj是C的扩展类但不覆盖C.method的D类的实例。在这种情况下，检查呼叫站点是否可以转换为由SingleTargetCallStub实现的单个目标状态（见RawSingleTargetCache）。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/aot-ic-singletarget.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;此存根基于以下事实：对于AOT编译，大多数类都使用继承层次结构的深度优先遍历来分配整数ID。如果C是具有D0，…，Dn子类的基类，并且没有一个覆盖C.method，则C.:cid &amp;lt;= classId（obj）&amp;lt;= max（D0.:cid，…，Dn .:cid）表示obj.method解析为C.method。在这种情况下，我们可以将类ID范围检查（单个目标状态）用于C的所有子类，而不是与单个类（单态）进行比较&lt;/p&gt;

&lt;p&gt;否则，呼叫站点将切换为使用线性搜索内联缓存，类似于在JIT模式下使用的缓存。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/aot-ic-linear.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;最后，如果线性数组中的检查数量超过阈值，则呼叫站点将切换为使用类似字典的结构&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dart_vm/vm_run/aot-ic-dictionary.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;四附录&quot;&gt;四、附录&lt;/h2&gt;
&lt;h4 id=&quot;41-源码说明&quot;&gt;4.1 源码说明&lt;/h4&gt;

&lt;p&gt;整个过程相关的核心源码，简要说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;runtime/vm/isolate.h： isolate对象&lt;/li&gt;
  &lt;li&gt;runtime/vm/thread.h：与连接到isolate对象的线程关联的状态&lt;/li&gt;
  &lt;li&gt;runtime/vm/heap/heap.h： isolate的堆&lt;/li&gt;
  &lt;li&gt;raw_object.h： 虚拟机内部对象&lt;/li&gt;
  &lt;li&gt;ast.dart：定义描述内核AST的类&lt;/li&gt;
  &lt;li&gt;kernel_loader.cc：其中的LoadEntireProgram()方法用于将内核AST反序列化为相应虚拟机对象的入口点&lt;/li&gt;
  &lt;li&gt;kernel_service.dart：实现了Kernel Service isolate&lt;/li&gt;
  &lt;li&gt;kernel_isolate.cc：将Dart实现粘合到VM的其余部分&lt;/li&gt;
  &lt;li&gt;pkg/front_end：用于解析Dart源码和构建内核AST&lt;/li&gt;
  &lt;li&gt;pkg/vm: 托管了大多数基于内核的VM特定功能，例如各种内核到内核的转换；由于历史原因，某些转换还位于pkg/kernel;&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler: 编译器源码&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler/jit/compiler.cc：编译管道入口点&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler/backend/il.h： IL的定义&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc： 其中的BuildGraph(), 内核到IL的翻译开始，处理各种人工功能的IL的构建&lt;/li&gt;
  &lt;li&gt;runtime/vm/stub_code_x64.cc：其中StubCode::GenerateNArgsCheckInlineCacheStub()，为内联缓存存根生成机器代码&lt;/li&gt;
  &lt;li&gt;runtime/vm/runtime_entry.cc：其中InlineCacheMissHandler()处理IC没有命中的情况&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler/compiler_pass.cc: 定义优化编译器的遍历及其顺序&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler/jit/jit_call_specializer.h：进行大多数基于类型反馈的专业化&lt;/li&gt;
  &lt;li&gt;runtime/vm/deopt_instructions.cc： 反优化过程&lt;/li&gt;
  &lt;li&gt;runtime/vm/clustered_snapshot.cc：处理快照的序列化和反序列化。API函数家族Dart_CreateXyzSnapshot[AsAssembly]负责写出堆的快照，比如 Dart_CreateAppJITSnapshotAsBlobs 和Dart_CreateAppAOTSnapshotAsAssembly。&lt;/li&gt;
  &lt;li&gt;runtime/vm/dart_api_impl.cc： 其中Dart_CreateIsolate可以选择获取快照数据以开始isolate。&lt;/li&gt;
  &lt;li&gt;pkg/vm/lib/transformations/type_flow/transformer.dart: TFA（类型流分析）以及基于TFA结果转换的切入点&lt;/li&gt;
  &lt;li&gt;runtime/vm/compiler/aot/precompiler.cc：其中Precompiler::DoCompileAll()是整个AOT编译的切入点&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;42-参考资料&quot;&gt;4.2 参考资料&lt;/h4&gt;

&lt;p&gt;https://mrale.ph/dartvm/&lt;/p&gt;
</description>
        <pubDate>Sat, 05 Oct 2019 22:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/10/05/dart_vm/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/10/05/dart_vm/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>解读Dart虚拟机的参数列表</title>
        <description>&lt;h2 id=&quot;一概述&quot;&gt;一、概述&lt;/h2&gt;
&lt;p&gt;在third_party/dart/runtime/vm/flag_list.h定义了Dart虚拟机中所有标志的列表，标志分为以下几大类别：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Product标记：可以在任何部署模式中设置，包括Product模式&lt;/li&gt;
  &lt;li&gt;Release标志：通常可用的标志，除Product模式以外&lt;/li&gt;
  &lt;li&gt;Precompile标志：通常可用的标志，除Product模式或已预编译的运行时以外&lt;/li&gt;
  &lt;li&gt;Debug标志：只能在启用C++断言的VM调试模式中设置&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Product、Release、Precompile、Debug这四类可控参数，可使用的范围逐次递减，比如Product flags可用于所有模式，Debug flags只能用于调试模式。Dart虚拟机总共有106个flags参数&lt;/p&gt;

&lt;h2 id=&quot;二flags参数&quot;&gt;二、flags参数&lt;/h2&gt;

&lt;h4 id=&quot;21-product-flags&quot;&gt;2.1 Product flags&lt;/h4&gt;

&lt;p&gt;用法：PRODUCT_FLAG_MARCO（名称，类型，默认值，注解）&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;名称&lt;/th&gt;
      &lt;th&gt;默认值&lt;/th&gt;
      &lt;th&gt;注解&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;collect_dynamic_function_names&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;收集所有动态函数名称以标识唯一目标&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_kernel_expression_compilation&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;启用内核前端来编译表达式&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_mirrors&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;允许导入dart:mirrors&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_ffi&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;允许导入dart:ffi&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;guess_icdata_cid&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;创建算法等操作的类型反馈&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;lazy_dispatchers&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;懒惰地生成调度程序&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;polymorphic_with_deopt&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;反优化的多态调用、巨形调用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;reorder_basic_blocks&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;对基本块重新排序&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_bare_instructions&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;启用裸指令模式&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;truncating_left_shift&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;尽可能优化左移以截断&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_cha_deopt&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;使用类层次分析，即使会导致反优化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_strong_mode_types&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;基于强模式类型的优化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_slow_path_sharing&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;启用共享慢速路径代码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_multiple_entrypoints&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;启用多个入口点&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;experimental_unsafe_mode_use_ at_your_own_risk&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;省略运行时强模式类型检查并禁用基于类型的优化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;abort_on_oom&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;如果内存分配失败则中止，仅与–old-gen-heap-size一起使用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;collect_code&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;尝试GC不常用代码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dwarf_stack_traces&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在dylib快照中发出dwarf行号和内联信息，而不表示堆栈跟踪&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;fields_may_be_reset&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;不要优化静态字段初始化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;link_natives_lazily&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;懒加载链接本地调用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;precompiled_mode&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;预编译编译器模式&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;print_snapshot_sizes&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;打印生成snapshot的大小&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;print_snapshot_sizes_verbose&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;打印生成snapshot的详细大小&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;print_benchmarking_metrics&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;打印其他内存和延迟指标以进行基准测试&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;shared_slow_path_triggers_gc&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;测试：慢路径触发GC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_strong_mode_types&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪基于强模式类型的优化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_bytecode_compiler&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;从字节码编译&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_compactor&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;当在旧空间执行GC时则压缩堆&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_testing_pragmas&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;启用神奇的编译指示以进行测试&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_interpreter&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;启用解释内核字节码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verify_entry_points&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;通过native API访问无效成员时抛出API错误&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;background_compilation&lt;/td&gt;
      &lt;td&gt;USING_MULTICORE&lt;/td&gt;
      &lt;td&gt;根据是否多核来决定是否后台运行优化编译&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;concurrent_mark&lt;/td&gt;
      &lt;td&gt;USING_MULTICORE&lt;/td&gt;
      &lt;td&gt;老年代的并发标记&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;concurrent_sweep&lt;/td&gt;
      &lt;td&gt;USING_MULTICORE&lt;/td&gt;
      &lt;td&gt;老年代的并发扫描&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_field_guards&lt;/td&gt;
      &lt;td&gt;!USING_DBC&lt;/td&gt;
      &lt;td&gt;使用字段gurad，跟踪字段类型&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;interpret_irregexp&lt;/td&gt;
      &lt;td&gt;USING_DBC&lt;/td&gt;
      &lt;td&gt;使用irregexp字节码解释器&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;causal_async_stacks&lt;/td&gt;
      &lt;td&gt;!USING_PRODUCT&lt;/td&gt;
      &lt;td&gt;非product 则开启改进异步堆栈&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;marker_tasks&lt;/td&gt;
      &lt;td&gt;USING_MULTICORE ? 2 : 0&lt;/td&gt;
      &lt;td&gt;老生代GC标记的任务数，0代表在主线程执行&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;idle_timeout_micros&lt;/td&gt;
      &lt;td&gt;1000 * 1000&lt;/td&gt;
      &lt;td&gt;长时间后将空闲任务从线程池隔离，单位微秒&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;idle_duration_micros&lt;/td&gt;
      &lt;td&gt;500 * 1000&lt;/td&gt;
      &lt;td&gt;允许空闲任务运行的时长&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;old_gen_heap_size&lt;/td&gt;
      &lt;td&gt;(kWordSize &amp;lt;= 4) ? 1536 : 0&lt;/td&gt;
      &lt;td&gt;旧一代堆的最大大小，或0（无限制），单位MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;new_gen_semi_max_size&lt;/td&gt;
      &lt;td&gt;(kWordSize &amp;lt;= 4) ? 8 : 16&lt;/td&gt;
      &lt;td&gt;新一代半空间的最大大小，单位MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;new_gen_semi_initial_size&lt;/td&gt;
      &lt;td&gt;(kWordSize &amp;lt;= 4) ? 1 : 2&lt;/td&gt;
      &lt;td&gt;新一代半空间的最大初始大小，单位MB&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;compactor_tasks&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;并行压缩使用的任务数&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;getter_setter_ratio&lt;/td&gt;
      &lt;td&gt;13&lt;/td&gt;
      &lt;td&gt;用于double拆箱启发式的getter/setter使用率？&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;huge_method_cutoff_in_tokens&lt;/td&gt;
      &lt;td&gt;20000&lt;/td&gt;
      &lt;td&gt;令牌中的大量方法中断：禁用大量方法的优化？&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;max_polymorphic_checks&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;多态检查的最大数量，否则为巨形的？&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;max_equality_polymorphic_checks&lt;/td&gt;
      &lt;td&gt;32&lt;/td&gt;
      &lt;td&gt;等式运算符中的多态检查的最大数量&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;compilation_counter_threshold&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;在解释执行函数编译完成前的函数使用次数要求，-1表示从不&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;optimization_counter_threshold&lt;/td&gt;
      &lt;td&gt;30000&lt;/td&gt;
      &lt;td&gt;函数在优化前的用法计数值，-1表示从不&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;optimization_level&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;优化级别：1（有利大小），2（默认），3（有利速度）&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;optimization_level这是一个可以尝试的参数&lt;/p&gt;

&lt;h4 id=&quot;22-release-flags&quot;&gt;2.2 Release flags&lt;/h4&gt;
&lt;p&gt;用法：RELEASE_FLAG_MARCO（名称，product_value，类型，默认值，注解）&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;名称&lt;/th&gt;
      &lt;th&gt;product值&lt;/th&gt;
      &lt;th&gt;默认值&lt;/th&gt;
      &lt;th&gt;注解&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;eliminate_type_checks&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;静态类型分析允许时消除类型检查&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dedup_instructions&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;预编译时规范化指令&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;support_disassembler&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;支持反汇编&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;support_il_printer&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;支持IL打印&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;support_service&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;支持服务协议&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;disable_alloc_stubs_after_gc&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;压力测试标识&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;disassemble&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;反汇编dart代码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;disassemble_optimized&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;反汇编优化代码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dump_megamorphic_stats&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;dump巨形缓存统计信息&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dump_symbol_stats&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;dump符合表统计信息&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable_asserts&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;启用断言语句&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;log_marker_tasks&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;记录老年代GC标记任务的调试信息&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;randomize_optimization_counter&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;基于每个功能随机化优化计数器阈值，用于测试&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;pause_isolates_on_start&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在isolate开始前暂停&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;pause_isolates_on_exit&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在isolate退出前暂停&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;pause_isolates_on_unhandled_exceptions&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在isolate发生未捕获异常前暂停&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;print_ssa_liveranges&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;内存分配后打印有效范围&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;print_stacktrace_at_api_error&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;当API发生错误时，打印native堆栈&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;profiler&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;开启profiler&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;profiler_native_memory&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;开启native内存统计收集&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_profiler&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪profiler&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_field_guards&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪字段cids的变化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verify_after_gc&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在GC之后启用堆验证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verify_before_gc&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在GC之前启用堆验证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verbose_gc&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;开启详细GC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verbose_gc_hdr&lt;/td&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;40&lt;/td&gt;
      &lt;td&gt;打印详细的GC标头间隔&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;23-precompile-flags&quot;&gt;2.3 Precompile flags&lt;/h4&gt;
&lt;p&gt;用法：PRECOMPILE_FLAG_MARCO（名称，precompiled_value，product_value，类型，默认值，注释）&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;名称&lt;/th&gt;
      &lt;th&gt;precompiled值&lt;/th&gt;
      &lt;th&gt;product值&lt;/th&gt;
      &lt;th&gt;默认值&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;load_deferred_eagerly&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;急切加载延迟的库&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use_osr&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;使用OSR&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;async_debugger&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;调试器支持异步功能&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;support_reload&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt;支持isolate重新加载&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;force_clone_compiler_objects&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;强制克隆编译器中所需的对象（ICData和字段）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;stress_async_stacks&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;压测异步堆栈&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_irregexp&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪irregexps&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;deoptimize_alot&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;取消优化，从native条目返回到dart代码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;deoptimize_every&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;在每N次堆栈溢出检查中取消优化&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;24-debug-flags&quot;&gt;2.4 Debug flags&lt;/h4&gt;
&lt;p&gt;用法：DEBUG_FLAG_MARCO（名称，类型，默认值，注解）&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;名称&lt;/th&gt;
      &lt;th&gt;默认值&lt;/th&gt;
      &lt;th&gt;注解&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;print_variable_descriptors&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在反汇编中打印变量描述符&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_cha&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪类层次分析(CHA)操作&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_ic&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪IC处理？&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_ic_miss_in_optimized&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪优化中的IC未命中情况&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_intrinsified_natives&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪是否调用固有native&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_isolates&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪isolate的创建与关闭&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_handles&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪handles的分配&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_kernel_binary&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪内核的读写&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_natives&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪native调用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_optimization&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;打印优化详情&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_profiler_verbose&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪profiler详情&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_runtime_calls&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪runtime调用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_ssa_allocator&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪通过SSA的寄存器分配&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_type_checks&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪运行时类型检测&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_patching&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪代码修补&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_optimized_ic_calls&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪优化代码中的IC调用？&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace_zones&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;跟踪zone的内存分配大小&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verify_gc_contains&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;在GC期间开启地址是否包含的验证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verify_on_transition&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;验证dart/vm的过渡？&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;support_rr&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt;支持在RR中运行？&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;默认值全部都为false，&lt;/p&gt;

&lt;h2 id=&quot;三实现原理&quot;&gt;三、实现原理&lt;/h2&gt;

&lt;h4 id=&quot;31-flag_list&quot;&gt;3.1 FLAG_LIST&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/flags.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;FLAG_LIST(PRODUCT_FLAG_MARCO,
          RELEASE_FLAG_MARCO,
          DEBUG_FLAG_MARCO,
          PRECOMPILE_FLAG_MARCO)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;FLAG_LIST列举了所有的宏定义，这里有四种不同的宏，接下来逐一展开说明&lt;/p&gt;

&lt;h4 id=&quot;32-flag宏定义&quot;&gt;3.2 flag宏定义&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/flags.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;// (1) Product标记：可以在任何部署模式中设置
#define PRODUCT_FLAG_MARCO(name, type, default_value, comment)                 \
  type FLAG_##name = Flags::Register_##type(&amp;amp;FLAG_##name, #name, default_value, comment);

// (2) Release标志：通常可用的标志，除Product模式以外
#if !defined(PRODUCT)
#define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
  type FLAG_##name = Flags::Register_##type(&amp;amp;FLAG_##name, #name, default_value, comment);

// (3) Precompile标志：通常可用的标志，除Product模式或已预编译的运行时以外
#if !defined(PRODUCT) &amp;amp;&amp;amp; !defined(DART_PRECOMPILED_RUNTIME)
#define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type, default_value, comment) \
  type FLAG_##name = Flags::Register_##type(&amp;amp;FLAG_##name, #name, default_value, comment);

// (4) Debug标志：只能在debug调试模式运行
#if defined(DEBUG)  
#define DEBUG_FLAG_MARCO(name, type, default_value, comment)                   \
  type FLAG_##name =  Flags::Register_##type(&amp;amp;FLAG_##name, #name, default_value, comment);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里涉及到3个宏定义：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PRODUCT：代表Product模式；&lt;/li&gt;
  &lt;li&gt;DART_PRECOMPILED_RUNTIME：代表运行时已预编译模式；&lt;/li&gt;
  &lt;li&gt;DEBUG：代表调试模式；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;可见，宏定义最终都是调用Flags::Register_XXX()方法，这里以FLAG_LIST中的其中一条定义来展开说明：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;P(collect_code, bool, false, &quot;Attempt to GC infrequently used code.&quot;)
//展开后等价如下
type FLAG_collect_code = Flags::Register_bool(&amp;amp;FLAG_collect_code, collect_code, false,
    &quot;Attempt to GC infrequently used code.&quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;33-flagsregister_bool&quot;&gt;3.3 Flags::Register_bool&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/flags.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;bool Flags::Register_bool(bool* addr,
                          const char* name,
                          bool default_value,
                          const char* comment) {
  Flag* flag = Lookup(name);  //[见小节3.4]
  if (flag != NULL) {
    return default_value;
  }
  flag = new Flag(name, comment, addr, Flag::kBoolean);
  AddFlag(flag);
  return default_value;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;34-flagslookup&quot;&gt;3.4 Flags::Lookup&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/flags.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Flag* Flags::Lookup(const char* name) {
  //遍历flags_来查找是否已存在
  for (intptr_t i = 0; i &amp;lt; num_flags_; i++) {
    Flag* flag = flags_[i];
    if (strcmp(flag-&amp;gt;name_, name) == 0) {
      return flag;
    }
  }
  return NULL;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Flags类中有3个重要的静态成员变量：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static Flag** flags_; //记录所有的flags对象指针
static intptr_t capacity_;  //代表数组的容量大小
static intptr_t num_flags_;  //代表当前flags对象指针的个数
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;35-flag初始化&quot;&gt;3.5 Flag初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/flags.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Flag {
  Flag(const char* name, const char* comment, void* addr, FlagType type)
      : name_(name), comment_(comment), addr_(addr), type_(type) {}

  const char* name_;
  const char* comment_;
  union {
    void* addr_;
    bool* bool_ptr_;
    int* int_ptr_;
    uint64_t* uint64_ptr_;
    charp* charp_ptr_;
    FlagHandler flag_handler_;
    OptionHandler option_handler_;
  };
  FlagType type_;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;36-flagsaddflag&quot;&gt;3.6 Flags::AddFlag&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/flags.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Flag {

  void Flags::AddFlag(Flag* flag) {
    if (num_flags_ == capacity_) {
      if (flags_ == NULL) {
        capacity_ = 256;  //初始化大小为256
        flags_ = new Flag*[capacity_];
      } else {
        intptr_t new_capacity = capacity_ * 2; //扩容
        Flag** new_flags = new Flag*[new_capacity];
        for (intptr_t i = 0; i &amp;lt; num_flags_; i++) {
          new_flags[i] = flags_[i];
        }
        delete[] flags_;
        flags_ = new_flags;
        capacity_ = new_capacity;
      }
    }
    //将flag记录到flags_
    flags_[num_flags_++] = flag;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最终，所有的flag信息都记录在Flags类的静态成员变量flags_中。&lt;/p&gt;

&lt;h2 id=&quot;四总结&quot;&gt;四、总结&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Product标记：可以在任何部署模式中设置&lt;/li&gt;
  &lt;li&gt;Release标志：通常可用的标志，除Product模式以外&lt;/li&gt;
  &lt;li&gt;Precompile标志：通常可用的标志，除Product模式或已预编译的运行时以外&lt;/li&gt;
  &lt;li&gt;Debug标志：只能在启用C++断言的VM调试模式中设置&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 22 Sep 2019 21:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/09/22/dartvm_flags/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/09/22/dartvm_flags/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>Flutter机器码生成gen_snapshot</title>
        <description>&lt;h2 id=&quot;一概述&quot;&gt;一、概述&lt;/h2&gt;

&lt;p&gt;书接上文&lt;a href=&quot;http://gityuan.com/2019/09/07/flutter_run/&quot;&gt;源码解读Flutter run机制&lt;/a&gt;的第四节 flutter build aot命令将dart源码编译成AOT产物，其主要工作为前端编译器frontend_server和机器码生成，本文再来介绍机器码生成的工作原理。&lt;/p&gt;

&lt;h3 id=&quot;11-gensnapshot命令&quot;&gt;1.1 GenSnapshot命令&lt;/h3&gt;
&lt;p&gt;GenSnapshot.run具体命令根据前面的封装，针对Android和iOS平台各有不同：&lt;/p&gt;

&lt;h4 id=&quot;111-针对android平台&quot;&gt;1.1.1 针对Android平台&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;flutter/bin/cache/artifacts/engine/android-arm-release/darwin-x64/gen_snapshot                   \
  --causal_async_stacks                                                                          \
  --packages=.packages                                                                           \
  --deterministic                                                                                \
  --snapshot_kind=app-aot-blobs                                                                  \
  --vm_snapshot_data=build/app/intermediates/flutter/release/vm_snapshot_data                    \
  --isolate_snapshot_data=build/app/intermediates/flutter/release/isolate_snapshot_data          \
  --vm_snapshot_instructions=build/app/intermediates/flutter/release/vm_snapshot_instr           \
  --isolate_snapshot_instructions=build/app/intermediates/flutter/release/isolate_snapshot_instr \
  --no-sim-use-hardfp                                                                            \
  --no-use-integer-division                                                                      \
  build/app/intermediates/flutter/release/app.dill
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上述命令用于Android平台将dart kernel转换为机器码。&lt;/p&gt;

&lt;h4 id=&quot;112-针对ios平台&quot;&gt;1.1.2 针对iOS平台&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;/usr/bin/arch -x86_64 flutter/bin/cache/artifacts/engine/ios-release/gen_snapshot \
  --causal_async_stacks                                                           \
  --deterministic                                                                 \
  --snapshot_kind=app-aot-assembly                                                \
  --assembly=build/aot/arm64/snapshot_assembly.S                                  \
  build/aot/app.dill                                                              
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上述命令用于iOS平台将dart kernel转换为机器码。&lt;/p&gt;

&lt;h3 id=&quot;12-机器码生成流程图&quot;&gt;1.2 机器码生成流程图&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/img/flutter_compile/SeqCodeGen.jpg&quot;&gt;点击查看大图&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_compile/SeqCodeGen.jpg&quot; alt=&quot;SeqCodeGen&quot; /&gt;&lt;/p&gt;

&lt;p&gt;此处gen_snapshot是一个二进制可执行文件，所对应的执行方法源码为third_party/dart/runtime/bin/gen_snapshot.cc，gen_snapshot将dart代码生成AOT二进制机器码，其中重点过程在precompiler.cc中的DoCompileAll()。&lt;/p&gt;

&lt;h4 id=&quot;121-小结&quot;&gt;1.2.1 小结&lt;/h4&gt;

&lt;p&gt;先通过Dart_Initialize()来初始化Dart虚拟机环境，&lt;/p&gt;

&lt;h4 id=&quot;122-snapshot类型&quot;&gt;1.2.2 snapshot类型&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;类型&lt;/th&gt;
      &lt;th&gt;名称&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;kCore&lt;/td&gt;
      &lt;td&gt;core&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kCoreJIT&lt;/td&gt;
      &lt;td&gt;core-jit&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kApp&lt;/td&gt;
      &lt;td&gt;app&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kAppJIT&lt;/td&gt;
      &lt;td&gt;app-jit&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kAppAOTBlobs&lt;/td&gt;
      &lt;td&gt;app-aot-blobs&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kAppAOTAssembly&lt;/td&gt;
      &lt;td&gt;app-aot-assembly&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kVMAOTAssembly&lt;/td&gt;
      &lt;td&gt;vm-aot-assembly&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;二源码解读gensnapshot&quot;&gt;二、源码解读GenSnapshot&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BuildAotCommand.runCommand
  AOTSnapshotter.build
    GenSnapshot.run
      gen_snapshot.main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;21-gen_snapshotmain&quot;&gt;2.1 gen_snapshot.main&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/gen_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;int main(int argc, char** argv) {
  const int EXTRA_VM_ARGUMENTS = 7;
  CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
  CommandLineOptions inputs(argc);

  //从命令行运行时，除非指定其他参数，否则使用更大的新一代半空间大小和更快的新一代生长因子
  if (kWordSize &amp;lt;= 4) {
    vm_options.AddArgument(&quot;--new_gen_semi_max_size=16&quot;);
  } else {
    vm_options.AddArgument(&quot;--new_gen_semi_max_size=32&quot;);
  }
  vm_options.AddArgument(&quot;--new_gen_growth_factor=4&quot;);
  vm_options.AddArgument(&quot;--deterministic&quot;);

  //解析命令行参数
  if (ParseArguments(argc, argv, &amp;amp;vm_options, &amp;amp;inputs) &amp;lt; 0) {
    return kErrorExitCode;
  }
  DartUtils::SetEnvironment(environment);

  if (!Platform::Initialize()) {
    return kErrorExitCode;
  }
  Console::SaveConfig();
  Loader::InitOnce();
  DartUtils::SetOriginalWorkingDirectory();
  //设置事件handler
  TimerUtils::InitOnce();
  EventHandler::Start();

  if (IsSnapshottingForPrecompilation()) {
    vm_options.AddArgument(&quot;--precompilation&quot;);
  } else if ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT)) {
    vm_options.AddArgument(&quot;--fields_may_be_reset&quot;);
  }

  char* error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());

  Dart_InitializeParams init_params;
  memset(&amp;amp;init_params, 0, sizeof(init_params));
  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
  init_params.file_open = DartUtils::OpenFile;
  init_params.file_read = DartUtils::ReadFile;
  init_params.file_write = DartUtils::WriteFile;
  init_params.file_close = DartUtils::CloseFile;
  init_params.entropy_source = DartUtils::EntropySource;
  init_params.start_kernel_isolate = false;

  std::unique_ptr&amp;lt;MappedMemory&amp;gt; mapped_vm_snapshot_data;
  std::unique_ptr&amp;lt;MappedMemory&amp;gt; mapped_vm_snapshot_instructions;
  std::unique_ptr&amp;lt;MappedMemory&amp;gt; mapped_isolate_snapshot_data;
  std::unique_ptr&amp;lt;MappedMemory&amp;gt; mapped_isolate_snapshot_instructions;
  //将这4个产物文件mmap到内存
  if (load_vm_snapshot_data_filename != NULL) {
    mapped_vm_snapshot_data =
        MapFile(load_vm_snapshot_data_filename, File::kReadOnly,
                &amp;amp;init_params.vm_snapshot_data);
  }
  if (load_vm_snapshot_instructions_filename != NULL) {
    mapped_vm_snapshot_instructions =
        MapFile(load_vm_snapshot_instructions_filename, File::kReadExecute,
                &amp;amp;init_params.vm_snapshot_instructions);
  }
  if (load_isolate_snapshot_data_filename) {
    mapped_isolate_snapshot_data =
        MapFile(load_isolate_snapshot_data_filename, File::kReadOnly,
                &amp;amp;isolate_snapshot_data);
  }
  if (load_isolate_snapshot_instructions_filename != NULL) {
    mapped_isolate_snapshot_instructions =
        MapFile(load_isolate_snapshot_instructions_filename, File::kReadExecute,
                &amp;amp;isolate_snapshot_instructions);
  }
  // 初始化Dart虚拟机 [见小节2.1.1]
  error = Dart_Initialize(&amp;amp;init_params);
  //[见小节2.2]
  int result = CreateIsolateAndSnapshot(inputs);
  // 回收Dart虚拟机
  error = Dart_Cleanup();
  EventHandler::Stop();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;初始化参数，并将这4个产物文件mmap到内存&lt;/li&gt;
  &lt;li&gt;执行Dart_Initialize()来初始化Dart虚拟机环境&lt;/li&gt;
  &lt;li&gt;CreateIsolateAndSnapshot&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;211-dart_initialize&quot;&gt;2.1.1 Dart_Initialize&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dart_api_impl.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DART_EXPORT char* Dart_Initialize(Dart_InitializeParams* params) {
  ...
  return Dart::Init(params-&amp;gt;vm_snapshot_data, params-&amp;gt;vm_snapshot_instructions,
                    params-&amp;gt;create, params-&amp;gt;shutdown, params-&amp;gt;cleanup,
                    params-&amp;gt;thread_exit, params-&amp;gt;file_open, params-&amp;gt;file_read,
                    params-&amp;gt;file_write, params-&amp;gt;file_close,
                    params-&amp;gt;entropy_source, params-&amp;gt;get_service_assets,
                    params-&amp;gt;start_kernel_isolate);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://gityuan.com/2019/06/23/dart-vm/&quot;&gt;深入理解Dart虚拟机启动&lt;/a&gt;的[小节2.10]记录了Dart虚拟机的初始化过程。&lt;/p&gt;

&lt;h3 id=&quot;22-createisolateandsnapshot&quot;&gt;2.2 CreateIsolateAndSnapshot&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/gen_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static int CreateIsolateAndSnapshot(const CommandLineOptions&amp;amp; inputs) {
  uint8_t* kernel_buffer = NULL;
  intptr_t kernel_buffer_size = NULL;
  ReadFile(inputs.GetArgument(0), &amp;amp;kernel_buffer, &amp;amp;kernel_buffer_size);

  Dart_IsolateFlags isolate_flags;
  Dart_IsolateFlagsInitialize(&amp;amp;isolate_flags);
  if (IsSnapshottingForPrecompilation()) {
    isolate_flags.obfuscate = obfuscate;
    isolate_flags.entry_points = no_entry_points;
  }

  IsolateData* isolate_data = new IsolateData(NULL, NULL, NULL, NULL);
  Dart_Isolate isolate;
  char* error = NULL;
  //创建isolate
  if (isolate_snapshot_data == NULL) {
    // 将vmservice库加入到核心snapshot，因此将其加载到main isolate
    isolate_flags.load_vmservice_library = true;
    isolate = Dart_CreateIsolateFromKernel(NULL, NULL, kernel_buffer,
                                           kernel_buffer_size, &amp;amp;isolate_flags,
                                           isolate_data, &amp;amp;error);
  } else {
    isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data,
                                 isolate_snapshot_instructions, NULL, NULL,
                                 &amp;amp;isolate_flags, isolate_data, &amp;amp;error);
  }

  Dart_EnterScope();
  Dart_Handle result = Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback);

  result = Dart_SetRootLibrary(Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size));

  MaybeLoadExtraInputs(inputs);
  MaybeLoadCode();
  // 根据产物类别 来创建相应产物
  switch (snapshot_kind) {
    case kCore:
      CreateAndWriteCoreSnapshot();
      break;
    case kCoreJIT:
      CreateAndWriteCoreJITSnapshot();
      break;
    case kApp:
      CreateAndWriteAppSnapshot();
      break;
    case kAppJIT:
      CreateAndWriteAppJITSnapshot();
      break;
    case kAppAOTBlobs:
    case kAppAOTAssembly:
      //[见小节2.3]
      CreateAndWritePrecompiledSnapshot();
      break;
    case kVMAOTAssembly: {
      File* file = OpenFile(assembly_filename);
      RefCntReleaseScope&amp;lt;File&amp;gt; rs(file);
      result = Dart_CreateVMAOTSnapshotAsAssembly(StreamingWriteCallback, file);
      CHECK_RESULT(result);
      break;
    }
    default:
      UNREACHABLE();
  }

  Dart_ExitScope();
  Dart_ShutdownIsolate();
  return 0;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;编译产物类型有7类，见[小节1.2.2]。 根据不同类型调用不同的CreateAndWriteXXXSnapshot()方法：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;kCore：CreateAndWriteCoreSnapshot&lt;/li&gt;
  &lt;li&gt;kCoreJIT：CreateAndWriteCoreJITSnapshot&lt;/li&gt;
  &lt;li&gt;kApp：CreateAndWriteAppSnapshot&lt;/li&gt;
  &lt;li&gt;kAppJIT：CreateAndWriteAppJITSnapshot&lt;/li&gt;
  &lt;li&gt;kAppAOTBlobs：CreateAndWritePrecompiledSnapshot&lt;/li&gt;
  &lt;li&gt;kAppAOTAssembly：CreateAndWritePrecompiledSnapshot&lt;/li&gt;
  &lt;li&gt;kVMAOTAssembly：Dart_CreateVMAOTSnapshotAsAssembly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;此处介绍AOT模式下，接下来执行CreateAndWritePrecompiledSnapshot()过程。&lt;/p&gt;

&lt;h3 id=&quot;23-createandwriteprecompiledsnapshot&quot;&gt;2.3 CreateAndWritePrecompiledSnapshot&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/bin/gen_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static void CreateAndWritePrecompiledSnapshot() {
  Dart_Handle result;

  //使用指定的嵌入程序入口点进行预编译 [见小节2.4]
  result = Dart_Precompile();

  //创建一个预编译的snapshot
  bool as_assembly = assembly_filename != NULL;
  if (as_assembly) {
    // kAppAOTAssembly模式
    File* file = OpenFile(assembly_filename);
    RefCntReleaseScope&amp;lt;File&amp;gt; rs(file);
    //iOS采用该方式 [见小节三]
    result = Dart_CreateAppAOTSnapshotAsAssembly(StreamingWriteCallback, file);
  } else {
    // kAppAOTBlobs模式
    const uint8_t* shared_data = NULL;
    const uint8_t* shared_instructions = NULL;
    std::unique_ptr&amp;lt;MappedMemory&amp;gt; mapped_shared_data;
    std::unique_ptr&amp;lt;MappedMemory&amp;gt; mapped_shared_instructions;
    if (shared_blobs_filename != NULL) {
      AppSnapshot* shared_blobs = NULL;
      shared_blobs = Snapshot::TryReadAppSnapshot(shared_blobs_filename);
      const uint8_t* ignored;
      shared_blobs-&amp;gt;SetBuffers(&amp;amp;ignored, &amp;amp;ignored, &amp;amp;shared_data,
                               &amp;amp;shared_instructions);
    } else {
      if (shared_data_filename != NULL) {
        mapped_shared_data =
            MapFile(shared_data_filename, File::kReadOnly, &amp;amp;shared_data);
      }
      if (shared_instructions_filename != NULL) {
        mapped_shared_instructions =
            MapFile(shared_instructions_filename, File::kReadOnly,
                    &amp;amp;shared_instructions);
      }
    }
    ...
    //将snapshot写入buffer缓存 [见小节四]
    result = Dart_CreateAppAOTSnapshotAsBlobs(
        &amp;amp;vm_snapshot_data_buffer, &amp;amp;vm_snapshot_data_size,
        &amp;amp;vm_snapshot_instructions_buffer, &amp;amp;vm_snapshot_instructions_size,
        &amp;amp;isolate_snapshot_data_buffer, &amp;amp;isolate_snapshot_data_size,
        &amp;amp;isolate_snapshot_instructions_buffer, &amp;amp;isolate_snapshot_instructions_size,
        shared_data, shared_instructions);

    if (blobs_container_filename != NULL) {
      Snapshot::WriteAppSnapshot(
          blobs_container_filename, vm_snapshot_data_buffer,
          vm_snapshot_data_size, vm_snapshot_instructions_buffer,
          vm_snapshot_instructions_size, isolate_snapshot_data_buffer,
          isolate_snapshot_data_size, isolate_snapshot_instructions_buffer,
          isolate_snapshot_instructions_size);
    } else {
      // 将内存中的产物数据写入相应的文件
      WriteFile(vm_snapshot_data_filename,
            vm_snapshot_data_buffer, vm_snapshot_data_size);
      WriteFile(vm_snapshot_instructions_filename,
            vm_snapshot_instructions_buffer, vm_snapshot_instructions_size);
      WriteFile(isolate_snapshot_data_filename,
            isolate_snapshot_data_buffer, isolate_snapshot_data_size);
      WriteFile(isolate_snapshot_instructions_filename,
            isolate_snapshot_instructions_buffer, isolate_snapshot_instructions_size);
    }
  }

  // 如果需要，序列化混淆图
  if (obfuscation_map_filename != NULL) {
    uint8_t* buffer = NULL;
    intptr_t size = 0;
    result = Dart_GetObfuscationMap(&amp;amp;buffer, &amp;amp;size);
    WriteFile(obfuscation_map_filename, buffer, size);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;调用Dart_Precompile()执行AOT编译&lt;/li&gt;
  &lt;li&gt;将snapshot代码写入buffer&lt;/li&gt;
  &lt;li&gt;将buffer写入这四个二进制文件vm_snapshot_data，vm_snapshot_instructions，isolate_snapshot_data，isolate_snapshot_instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;该方法最终将Dart代码彻底编译为二进制可执行的机器码文件&lt;/p&gt;

&lt;h3 id=&quot;24-dart_precompile&quot;&gt;2.4 Dart_Precompile&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dart_api_impl.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DART_EXPORT Dart_Handle Dart_Precompile() {
  ...
#if defined(DART_PRECOMPILER)
  DARTSCOPE(Thread::Current());
  API_TIMELINE_BEGIN_END(T);
  if (!FLAG_precompiled_mode) {
    return Api::NewError(&quot;Flag --precompilation was not specified.&quot;);
  }
  Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
  if (Api::IsError(result)) {
    return result;
  }
  CHECK_CALLBACK_STATE(T);
  //[见小节2.4.1]
  CHECK_ERROR_HANDLE(Precompiler::CompileAll());
  return Api::Success();
#endif
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;241-compileall&quot;&gt;2.4.1 CompileAll&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/compiler/aot/precompiler.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;RawError* Precompiler::CompileAll() {
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    //创建Precompiler对象
    Precompiler precompiler(Thread::Current());
    //[见小节2.4.2]
    precompiler.DoCompileAll();
    return Error::null();
  } else {
    return Thread::Current()-&amp;gt;StealStickyError();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在Dart Runtime中生成FlowGraph对象，接着进行一系列执行流的优化，最后把优化后的FlowGraph对象转换为具体相应系统架构（arm/arm64等）的二进制指令&lt;/p&gt;

&lt;h4 id=&quot;242-docompileall&quot;&gt;2.4.2 DoCompileAll&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/compiler/aot/precompiler.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void Precompiler::DoCompileAll() {
  {
    StackZone stack_zone(T);
    zone_ = stack_zone.GetZone();

    if (FLAG_use_bare_instructions) {
      // 使用zone_来保障全局object对象池的生命周期能伴随整个AOT编译过程
      global_object_pool_builder_.InitializeWithZone(zone_);
    }

    {
      HANDLESCOPE(T);
      // 确保类层次稳定，因此会先支持CHA分析类层次结构
      FinalizeAllClasses();
      ClassFinalizer::SortClasses();

      // 收集类型使用情况信息，使我们可以决定何时/如何优化运行时类型测试
      TypeUsageInfo type_usage_info(T);

      // 一个类的子类的cid范围，用于is/as的类型检查
      HierarchyInfo hierarchy_info(T);

      // 预编译构造函数以计算信息，例如优化的指令数（用于内联启发法）
      ClassFinalizer::ClearAllCode(FLAG_use_bare_instructions);
      PrecompileConstructors();

      ClassFinalizer::ClearAllCode(FLAG_use_bare_instructions);

      // 所有存根都已经生成，它们都共享同一个池。 使用该池来初始化全局对象池，
      // 以确保存根和此处编译的代码都具有相同的池。
      if (FLAG_use_bare_instructions) {
        // 在这里使用任何存根来获取它的对象池（所有存根在裸指令模式下共享相同的对象池）
        const Code&amp;amp; code = StubCode::InterpretCall();
        const ObjectPool&amp;amp; stub_pool = ObjectPool::Handle(code.object_pool());

        global_object_pool_builder()-&amp;gt;Reset();
        stub_pool.CopyInto(global_object_pool_builder());

        //我们有两个需要使用新的全局对象池重新生成的全局代码对象，即
        // 大型未命中处理程序代码 和 构建方法提取器代码
        MegamorphicCacheTable::ReInitMissHandlerCode(
            isolate_, global_object_pool_builder());

        auto&amp;amp; stub_code = Code::Handle();

        stub_code = StubCode::GetBuildMethodExtractorStub(global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_build_method_extractor_code(stub_code);

        stub_code = StubCode::BuildIsolateSpecificNullErrorSharedWithFPURegsStub(
                global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_null_error_stub_with_fpu_regs_stub(stub_code);

        stub_code = StubCode::BuildIsolateSpecificNullErrorSharedWithoutFPURegsStub(
                global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_null_error_stub_without_fpu_regs_stub(stub_code);

        stub_code = StubCode::BuildIsolateSpecificStackOverflowSharedWithFPURegsStub(
                global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_stack_overflow_stub_with_fpu_regs_stub(stub_code);

        stub_code = StubCode::BuildIsolateSpecificStackOverflowSharedWithoutFPURegsStub(
                global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_stack_overflow_stub_without_fpu_regs_stub(stub_code);

        stub_code = StubCode::BuildIsolateSpecificWriteBarrierWrappersStub(
                global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_write_barrier_wrappers_stub(stub_code);

        stub_code = StubCode::BuildIsolateSpecificArrayWriteBarrierStub(
                global_object_pool_builder());
        I-&amp;gt;object_store()-&amp;gt;set_array_write_barrier_stub(stub_code);
      }

      CollectDynamicFunctionNames();

      // 从C++发生的分配和调用的起点添加为根
      AddRoots();
      // 将所有以@pragma（'vm：entry-point'）注释的值添加为根
      AddAnnotatedRoots();

      //编译前面找到的根作为目标，并逐步添加该目标的调用者，直到达到固定点为止
      Iterate();

      // 用新的[Type]专用存根替换安装在[Type]上的默认类型测试存根
      AttachOptimizedTypeTestingStub();

      if (FLAG_use_bare_instructions) {
        // 生成实际的对象池实例，并将其附加到对象存储。AOT运行时将在dart入口代码存根中使用它。
        const auto&amp;amp; pool = ObjectPool::Handle(
            ObjectPool::NewFromBuilder(*global_object_pool_builder()));
        I-&amp;gt;object_store()-&amp;gt;set_global_object_pool(pool);
        global_object_pool_builder()-&amp;gt;Reset();

        if (FLAG_print_gop) {
          THR_Print(&quot;Global object pool:\n&quot;);
          pool.DebugPrint();
        }
      }

      I-&amp;gt;set_compilation_allowed(false);

      TraceForRetainedFunctions();
      DropFunctions();
      DropFields();
      TraceTypesFromRetainedClasses();
      DropTypes();
      DropTypeArguments();

      // 在删除类之前清除这些类的死实例或者未使用的符号
      I-&amp;gt;object_store()-&amp;gt;set_unique_dynamic_targets(Array::null_array());
      Class&amp;amp; null_class = Class::Handle(Z);
      Function&amp;amp; null_function = Function::Handle(Z);
      Field&amp;amp; null_field = Field::Handle(Z);
      I-&amp;gt;object_store()-&amp;gt;set_future_class(null_class);
      I-&amp;gt;object_store()-&amp;gt;set_pragma_class(null_class);
      I-&amp;gt;object_store()-&amp;gt;set_pragma_name(null_field);
      I-&amp;gt;object_store()-&amp;gt;set_pragma_options(null_field);
      I-&amp;gt;object_store()-&amp;gt;set_completer_class(null_class);
      I-&amp;gt;object_store()-&amp;gt;set_symbol_class(null_class);
      I-&amp;gt;object_store()-&amp;gt;set_compiletime_error_class(null_class);
      I-&amp;gt;object_store()-&amp;gt;set_growable_list_factory(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_simple_instance_of_function(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_simple_instance_of_true_function(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_simple_instance_of_false_function(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_async_set_thread_stack_trace(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_async_star_move_next_helper(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_complete_on_async_return(null_function);
      I-&amp;gt;object_store()-&amp;gt;set_async_star_stream_controller(null_class);
      DropMetadata();
      DropLibraryEntries();
    }
    DropClasses();
    DropLibraries();

    BindStaticCalls();
    SwitchICCalls();
    Obfuscate();

    ProgramVisitor::Dedup();
    zone_ = NULL;
  }

  intptr_t symbols_before = -1;
  intptr_t symbols_after = -1;
  intptr_t capacity = -1;
  if (FLAG_trace_precompiler) {
    //获取symbol表的统计信息
    Symbols::GetStats(I, &amp;amp;symbols_before, &amp;amp;capacity);
  }

  Symbols::Compact();

  if (FLAG_trace_precompiler) {
    Symbols::GetStats(I, &amp;amp;symbols_after, &amp;amp;capacity);
    THR_Print(&quot;Precompiled %&quot; Pd &quot; functions,&quot;, function_count_);
    THR_Print(&quot; %&quot; Pd &quot; dynamic types,&quot;, class_count_);
    THR_Print(&quot; %&quot; Pd &quot; dynamic selectors.\n&quot;, selector_count_);

    THR_Print(&quot;Dropped %&quot; Pd &quot; functions,&quot;, dropped_function_count_);
    THR_Print(&quot; %&quot; Pd &quot; fields,&quot;, dropped_field_count_);
    THR_Print(&quot; %&quot; Pd &quot; symbols,&quot;, symbols_before - symbols_after);
    THR_Print(&quot; %&quot; Pd &quot; types,&quot;, dropped_type_count_);
    THR_Print(&quot; %&quot; Pd &quot; type arguments,&quot;, dropped_typearg_count_);
    THR_Print(&quot; %&quot; Pd &quot; classes,&quot;, dropped_class_count_);
    THR_Print(&quot; %&quot; Pd &quot; libraries.\n&quot;, dropped_library_count_);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这个过程比较复杂，其主要工作内容如下：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;FinalizeAllClasses()：确保类层次稳定，因此会先支持CHA分析类层次结构；&lt;/li&gt;
  &lt;li&gt;PrecompileConstructors()：预编译构造函数以计算信息，例如优化的指令数（用于内联启发法）；&lt;/li&gt;
  &lt;li&gt;StubCode：通过StubCode::InterpretCall得到的code来获取它的对象池，再利用StubCode::BuildXXX()系列方法获取的结果保存在object_store；&lt;/li&gt;
  &lt;li&gt;CollectDynamicFunctionNames()：收集动态函数的方法名；&lt;/li&gt;
  &lt;li&gt;AddRoots()：从C++发生的分配和调用的起点添加为根；&lt;/li&gt;
  &lt;li&gt;AddAnnotatedRoots()：将所有以@pragma（’vm：entry-point’）注释的值添加为根;&lt;/li&gt;
  &lt;li&gt;Iterate(): 这是编译最为核心的地方，编译前面找到的根作为目标，并逐步添加该目标的调用者，直到达到固定点为止；&lt;/li&gt;
  &lt;li&gt;DropXXX(): 调用DropFunctions，DropFields，DropTypes等一系列操作 去掉方法、字段、类、库等；&lt;/li&gt;
  &lt;li&gt;BindStaticCalls()：绑定静态调用方法，说明tree-shaker后并非所有的函数都会被编译；&lt;/li&gt;
  &lt;li&gt;SwitchICCalls()：已编译所有静态函数，则切到实例调用(instance call)队列，迭代所有对象池；&lt;/li&gt;
  &lt;li&gt;Obfuscate()：执行代码混淆操作，并保持混淆map表；&lt;/li&gt;
  &lt;li&gt;ProgramVisitor::Dedup()：清理各数据段的重复数据，比如CodeSourceMaps、StackMaps等；&lt;/li&gt;
  &lt;li&gt;Symbols::Compact(): 执行完整的垃圾回收，整理后压缩symbols；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;到此Dart_Precompile()过程执行完成。&lt;/p&gt;

&lt;p&gt;Dart_Precompile()执行完再回到[小节2.3]，再来分别看看产物生成的过程。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;iOS：执行Dart_CreateAppAOTSnapshotAsAssembly()方法；&lt;/li&gt;
  &lt;li&gt;Android：执行Dart_CreateAppAOTSnapshotAsBlobs()方法。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;三-ios快照产物生成&quot;&gt;三、 iOS快照产物生成&lt;/h2&gt;
&lt;h3 id=&quot;31-dart_createappaotsnapshotasassembly&quot;&gt;3.1 Dart_CreateAppAOTSnapshotAsAssembly&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dart_api_impl.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback,
                                    void* callback_data) {
#if defined(DART_PRECOMPILER)
  ...
  //初始化AssemblyImageWriter对象
  AssemblyImageWriter image_writer(T, callback, callback_data, NULL, NULL);
  uint8_t* vm_snapshot_data_buffer = NULL;
  uint8_t* isolate_snapshot_data_buffer = NULL;
  FullSnapshotWriter writer(Snapshot::kFullAOT, &amp;amp;vm_snapshot_data_buffer,
                            &amp;amp;isolate_snapshot_data_buffer, ApiReallocate,
                            &amp;amp;image_writer, &amp;amp;image_writer);
  //[见小节3.2]
  writer.WriteFullSnapshot();
  //[见小节3.7]
  image_writer.Finalize();
  return Api::Success();
#endif
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;创建AssemblyImageWriter对象过程，初始化其成员变量StreamingWriteStream类型的assembly_stream_和Dwarf*类型的dwarf_&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;assembly_stream_初始化：创建大小等于512KB的buffer_，callback_为StreamingWriteCallback，callback_为snapshot_assembly.S&lt;/li&gt;
  &lt;li&gt;dwarf_初始化：其成员变量stream_指向assembly_stream_；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;创建FullSnapshotWriter对象过程，初始化其成员变量kind_等于Snapshot::kFullAOT。vm_snapshot_data_buffer_和isolate_snapshot_data_buffer_分别指向vm_snapshot_data_buffer和isolate_snapshot_data_buffer的地址。&lt;/p&gt;

&lt;h3 id=&quot;32-writefullsnapshot&quot;&gt;3.2 WriteFullSnapshot&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/clustered_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void FullSnapshotWriter::WriteFullSnapshot() {
  intptr_t num_base_objects;
  if (vm_snapshot_data_buffer() != NULL) {
    //[见小节3.3]
    num_base_objects = WriteVMSnapshot();
  } else {
    num_base_objects = 0;
  }

  if (isolate_snapshot_data_buffer() != NULL) {
    //[见小节3.6]
    WriteIsolateSnapshot(num_base_objects);
  }

  if (FLAG_print_snapshot_sizes) {
    OS::Print(&quot;VMIsolate(CodeSize): %&quot; Pd &quot;\n&quot;, clustered_vm_size_);
    OS::Print(&quot;Isolate(CodeSize): %&quot; Pd &quot;\n&quot;, clustered_isolate_size_);
    OS::Print(&quot;ReadOnlyData(CodeSize): %&quot; Pd &quot;\n&quot;, mapped_data_size_);
    OS::Print(&quot;Instructions(CodeSize): %&quot; Pd &quot;\n&quot;, mapped_text_size_);
    OS::Print(&quot;Total(CodeSize): %&quot; Pd &quot;\n&quot;,
              clustered_vm_size_ + clustered_isolate_size_ + mapped_data_size_ +
                  mapped_text_size_);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;产物大小的分类来自于FullSnapshotWriter的几个成员变量&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;clustered_vm_size_：是vm的数据段，包含符号表和stub代码&lt;/li&gt;
  &lt;li&gt;clustered_isolate_size_：是isolate的数据段，包含object store&lt;/li&gt;
  &lt;li&gt;ReadOnlyData：是由vm和isolate的只读数据段组成&lt;/li&gt;
  &lt;li&gt;Instructions：是由vm和isolate的代码段组成&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;33-writevmsnapshot&quot;&gt;3.3 WriteVMSnapshot&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/clustered_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;intptr_t FullSnapshotWriter::WriteVMSnapshot() {
  Serializer serializer(thread(), kind_, vm_snapshot_data_buffer_, alloc_,
                        kInitialSize, vm_image_writer_, /*vm=*/true,
                        profile_writer_);

  serializer.ReserveHeader();  //预留空间来记录快照buffer的大小
  serializer.WriteVersionAndFeatures(true);
  const Array&amp;amp; symbols = Array::Handle(Dart::vm_isolate()-&amp;gt;object_store()-&amp;gt;symbol_table());
  //写入符号表 [见小节3.3.1]
  intptr_t num_objects = serializer.WriteVMSnapshot(symbols);
  serializer.FillHeader(serializer.kind());  //填充头部信息
  clustered_vm_size_ = serializer.bytes_written();

  if (Snapshot::IncludesCode(kind_)) {  //kFullAOT模式满足条件
    vm_image_writer_-&amp;gt;SetProfileWriter(profile_writer_);
    //[见小节3.4]
    vm_image_writer_-&amp;gt;Write(serializer.stream(), true);
    mapped_data_size_ += vm_image_writer_-&amp;gt;data_size(); //数据段
    mapped_text_size_ += vm_image_writer_-&amp;gt;text_size(); //代码段
    vm_image_writer_-&amp;gt;ResetOffsets();
    vm_image_writer_-&amp;gt;ClearProfileWriter();
  }

  //集群部分+直接映射的数据部分
  vm_isolate_snapshot_size_ = serializer.bytes_written();
  return num_objects;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;创建Serializer对象过程，初始化其成员变量WriteStream类型的stream_。VM snapshot的根节点是符号表和stub代码(App-AOT、App-JIT、Core-JIT)&lt;/p&gt;

&lt;p&gt;serializer通过其成员变量stream_写入如下内容：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;FillHeader：头部内容&lt;/li&gt;
  &lt;li&gt;WriteVersionAndFeatures：版本信息&lt;/li&gt;
  &lt;li&gt;WriteVMSnapshot：符号表&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;331-serializerwritevmsnapshot&quot;&gt;3.3.1 Serializer::WriteVMSnapshot&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/clustered_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;intptr_t Serializer::WriteVMSnapshot(const Array&amp;amp; symbols) {
  NoSafepointScope no_safepoint;
  //添加虚拟机isolate的基本对象
  AddVMIsolateBaseObjects();

  //VM snapshot的根节点 入栈，也就是是符号表和stub代码
  Push(symbols.raw());
  if (Snapshot::IncludesCode(kind_)) {
    for (intptr_t i = 0; i &amp;lt; StubCode::NumEntries(); i++) {
      Push(StubCode::EntryAt(i).raw());
    }
  }
  //写入stream_
  Serialize();

  //写入VM snapshot的根节点
  WriteRootRef(symbols.raw());
  if (Snapshot::IncludesCode(kind_)) {
    for (intptr_t i = 0; i &amp;lt; StubCode::NumEntries(); i++) {
      WriteRootRef(StubCode::EntryAt(i).raw());
    }
  }

  //  虚拟机isolate快照的完整 作为isolate快照的基本对象
  //返回对象个数
  return next_ref_index_ - 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;34-imagewriterwrite&quot;&gt;3.4 ImageWriter::Write&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/image_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void ImageWriter::Write(WriteStream* clustered_stream, bool vm) {
  Thread* thread = Thread::Current();
  Zone* zone = thread-&amp;gt;zone();
  Heap* heap = thread-&amp;gt;isolate()-&amp;gt;heap();

  //处理收集的原始指针，构建以下名称将分配在Dart堆
  for (intptr_t i = 0; i &amp;lt; instructions_.length(); i++) {
    InstructionsData&amp;amp; data = instructions_[i];
    const bool is_trampoline = data.trampoline_bytes != nullptr;
    if (is_trampoline) continue;

    data.insns_ = &amp;amp;Instructions::Handle(zone, data.raw_insns_);
    data.code_ = &amp;amp;Code::Handle(zone, data.raw_code_);

    //重置isolate快照的对象id
    heap-&amp;gt;SetObjectId(data.insns_-&amp;gt;raw(), 0);
  }
  for (intptr_t i = 0; i &amp;lt; objects_.length(); i++) {
    ObjectData&amp;amp; data = objects_[i];
    data.obj_ = &amp;amp;Object::Handle(zone, data.raw_obj_);
  }

  //在群集快照之后附加直接映射的RO数据对象
  offset_space_ = vm ? V8SnapshotProfileWriter::kVmData
                     : V8SnapshotProfileWriter::kIsolateData;
  //[见小节3.4.1]
  WriteROData(clustered_stream);

  offset_space_ = vm ? V8SnapshotProfileWriter::kVmText
                     : V8SnapshotProfileWriter::kIsolateText;
  //[见小节3.5]
  WriteText(clustered_stream, vm);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处clustered_stream的是指Serializer的成员变量stream_。&lt;/p&gt;

&lt;h4 id=&quot;341-writerodata&quot;&gt;3.4.1 WriteROData&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/image_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void ImageWriter::WriteROData(WriteStream* stream) {
  stream-&amp;gt;Align(OS::kMaxPreferredCodeAlignment);  //32位对齐

  //堆页面的起点
  intptr_t section_start = stream-&amp;gt;Position();
  stream-&amp;gt;WriteWord(next_data_offset_);  // Data length.
  stream-&amp;gt;Align(OS::kMaxPreferredCodeAlignment);

  //堆页面中对象的起点
  for (intptr_t i = 0; i &amp;lt; objects_.length(); i++) {
    const Object&amp;amp; obj = *objects_[i].obj_;
    AutoTraceImage(obj, section_start, stream);

    NoSafepointScope no_safepoint;
    uword start = reinterpret_cast&amp;lt;uword&amp;gt;(obj.raw()) - kHeapObjectTag;
    uword end = start + obj.raw()-&amp;gt;HeapSize();

    //写有标记和只读位的对象标头
    uword marked_tags = obj.raw()-&amp;gt;ptr()-&amp;gt;tags_;
    marked_tags = RawObject::OldBit::update(true, marked_tags);
    marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
    marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
    marked_tags = RawObject::NewBit::update(false, marked_tags);

    stream-&amp;gt;WriteWord(marked_tags);
    start += sizeof(uword);
    for (uword* cursor = reinterpret_cast&amp;lt;uword*&amp;gt;(start);
         cursor &amp;lt; reinterpret_cast&amp;lt;uword*&amp;gt;(end); cursor++) {
      stream-&amp;gt;WriteWord(*cursor);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;35-assemblyimagewriterwritetext&quot;&gt;3.5 AssemblyImageWriter::WriteText&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; ]third_party/dart/runtime/vm/image_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
  Zone* zone = Thread::Current()-&amp;gt;zone();
  //写入头部
  const char* instructions_symbol = vm ? &quot;_kDartVmSnapshotInstructions&quot; : &quot;_kDartIsolateSnapshotInstructions&quot;;
  assembly_stream_.Print(&quot;.text\n&quot;);
  assembly_stream_.Print(&quot;.globl %s\n&quot;, instructions_symbol);
  assembly_stream_.Print(&quot;.balign %&quot; Pd &quot;, 0\n&quot;, VirtualMemory::PageSize());
  assembly_stream_.Print(&quot;%s:\n&quot;, instructions_symbol);

  //写入头部空白字符，使得指令快照看起来像堆页
  intptr_t instructions_length = next_text_offset_;
  WriteWordLiteralText(instructions_length);
  intptr_t header_words = Image::kHeaderSize / sizeof(uword);
  for (intptr_t i = 1; i &amp;lt; header_words; i++) {
    WriteWordLiteralText(0);
  }

  //写入序幕.cfi_xxx
  FrameUnwindPrologue();

  Object&amp;amp; owner = Object::Handle(zone);
  String&amp;amp; str = String::Handle(zone);
  ObjectStore* object_store = Isolate::Current()-&amp;gt;object_store();

  TypeTestingStubNamer tts;
  intptr_t text_offset = 0;

  for (intptr_t i = 0; i &amp;lt; instructions_.length(); i++) {
    auto&amp;amp; data = instructions_[i];
    const bool is_trampoline = data.trampoline_bytes != nullptr;
    if (is_trampoline) {     //针对跳床函数
      const auto start = reinterpret_cast&amp;lt;uword&amp;gt;(data.trampoline_bytes);
      const auto end = start + data.trampline_length;
       //写入.quad xxx字符串
      text_offset += WriteByteSequence(start, end);
      delete[] data.trampoline_bytes;
      data.trampoline_bytes = nullptr;
      continue;
    }

    const intptr_t instr_start = text_offset;
    const Instructions&amp;amp; insns = *data.insns_;
    const Code&amp;amp; code = *data.code_;
    // 1. 写入 头部到入口点
    {
      NoSafepointScope no_safepoint;

      uword beginning = reinterpret_cast&amp;lt;uword&amp;gt;(insns.raw_ptr());
      uword entry = beginning + Instructions::HeaderSize(); //ARM64 32位对齐

      //指令的只读标记
      uword marked_tags = insns.raw_ptr()-&amp;gt;tags_;
      marked_tags = RawObject::OldBit::update(true, marked_tags);
      marked_tags = RawObject::OldAndNotMarkedBit::update(false, marked_tags);
      marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
      marked_tags = RawObject::NewBit::update(false, marked_tags);
      //写入标记
      WriteWordLiteralText(marked_tags);
      beginning += sizeof(uword);
      text_offset += sizeof(uword);
      text_offset += WriteByteSequence(beginning, entry);
    }

    // 2. 在入口点写入标签
    owner = code.owner();
    if (owner.IsNull()) {  
      // owner为空，说明是一个常规的stub，其中stub列表定义在stub_code_list.h中的VM_STUB_CODE_LIST
      const char* name = StubCode::NameOfStub(insns.EntryPoint());
      if (name != nullptr) {
        assembly_stream_.Print(&quot;Precompiled_Stub_%s:\n&quot;, name);
      } else {
        if (name == nullptr) {
          // isolate专有的stub代码[见小节3.5.1]
          name = NameOfStubIsolateSpecificStub(object_store, code);
        }
        assembly_stream_.Print(&quot;Precompiled__%s:\n&quot;, name);
      }
    } else if (owner.IsClass()) {
      //owner为Class，说明是该类分配的stub，其中class列表定义在class_id.h中的CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY
      str = Class::Cast(owner).Name();
      const char* name = str.ToCString();
      EnsureAssemblerIdentifier(const_cast&amp;lt;char*&amp;gt;(name));
      assembly_stream_.Print(&quot;Precompiled_AllocationStub_%s_%&quot; Pd &quot;:\n&quot;, name,
                             i);
    } else if (owner.IsAbstractType()) {
      const char* name = tts.StubNameForType(AbstractType::Cast(owner));
      assembly_stream_.Print(&quot;Precompiled_%s:\n&quot;, name);
    } else if (owner.IsFunction()) { //owner为Function，说明是一个常规的dart函数
      const char* name = Function::Cast(owner).ToQualifiedCString();
      EnsureAssemblerIdentifier(const_cast&amp;lt;char*&amp;gt;(name));
      assembly_stream_.Print(&quot;Precompiled_%s_%&quot; Pd &quot;:\n&quot;, name, i);
    } else {
      UNREACHABLE();
    }

#ifdef DART_PRECOMPILER
    // 创建一个标签用于DWARF
    if (!code.IsNull()) {
      const intptr_t dwarf_index = dwarf_-&amp;gt;AddCode(code);
      assembly_stream_.Print(&quot;.Lcode%&quot; Pd &quot;:\n&quot;, dwarf_index);
    }
#endif

    {
      // 3. 写入 入口点到结束
      NoSafepointScope no_safepoint;
      uword beginning = reinterpret_cast&amp;lt;uword&amp;gt;(insns.raw_ptr());
      uword entry = beginning + Instructions::HeaderSize();
      uword payload_size = insns.raw()-&amp;gt;HeapSize() - insns.HeaderSize();
      uword end = entry + payload_size;
      text_offset += WriteByteSequence(entry, end);
    }
  }

  FrameUnwindEpilogue();

#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                  \
    defined(TARGET_OS_FUCHSIA)
  assembly_stream_.Print(&quot;.section .rodata\n&quot;);
#elif defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
  assembly_stream_.Print(&quot;.const\n&quot;);
#else
  UNIMPLEMENTED();
#endif
  //写入数据段
  const char* data_symbol = vm ? &quot;_kDartVmSnapshotData&quot; : &quot;_kDartIsolateSnapshotData&quot;;
  assembly_stream_.Print(&quot;.globl %s\n&quot;, data_symbol);
  assembly_stream_.Print(&quot;.balign %&quot; Pd &quot;, 0\n&quot;,
                         OS::kMaxPreferredCodeAlignment);
  assembly_stream_.Print(&quot;%s:\n&quot;, data_symbol);
  uword buffer = reinterpret_cast&amp;lt;uword&amp;gt;(clustered_stream-&amp;gt;buffer());
  intptr_t length = clustered_stream-&amp;gt;bytes_written();
  WriteByteSequence(buffer, buffer + length);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;351-nameofstubisolatespecificstub&quot;&gt;3.5.1 NameOfStubIsolateSpecificStub&lt;/h4&gt;
&lt;p&gt;[[-&amp;gt; ]third_party/dart/runtime/vm/image_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;const char* NameOfStubIsolateSpecificStub(ObjectStore* object_store,
                                          const Code&amp;amp; code) {
  if (code.raw() == object_store-&amp;gt;build_method_extractor_code()) {
    return &quot;_iso_stub_BuildMethodExtractorStub&quot;;
  } else if (code.raw() == object_store-&amp;gt;null_error_stub_with_fpu_regs_stub()) {
    return &quot;_iso_stub_NullErrorSharedWithFPURegsStub&quot;;
  } else if (code.raw() ==
             object_store-&amp;gt;null_error_stub_without_fpu_regs_stub()) {
    return &quot;_iso_stub_NullErrorSharedWithoutFPURegsStub&quot;;
  } else if (code.raw() ==
             object_store-&amp;gt;stack_overflow_stub_with_fpu_regs_stub()) {
    return &quot;_iso_stub_StackOverflowStubWithFPURegsStub&quot;;
  } else if (code.raw() ==
             object_store-&amp;gt;stack_overflow_stub_without_fpu_regs_stub()) {
    return &quot;_iso_stub_StackOverflowStubWithoutFPURegsStub&quot;;
  } else if (code.raw() == object_store-&amp;gt;write_barrier_wrappers_stub()) {
    return &quot;_iso_stub_WriteBarrierWrappersStub&quot;;
  } else if (code.raw() == object_store-&amp;gt;array_write_barrier_stub()) {
    return &quot;_iso_stub_ArrayWriteBarrierStub&quot;;
  }
  return nullptr;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;再回到[小节3.1]，执行完WriteVMSnapshot()方法，然后执行WriteIsolateSnapshot()方法。&lt;/p&gt;

&lt;h3 id=&quot;36-writeisolatesnapshot&quot;&gt;3.6 WriteIsolateSnapshot&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/clustered_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
  Serializer serializer(thread(), kind_, isolate_snapshot_data_buffer_, alloc_,
                        kInitialSize, isolate_image_writer_, /*vm=*/false,
                        profile_writer_);
  ObjectStore* object_store = isolate()-&amp;gt;object_store();

  serializer.ReserveHeader();
  serializer.WriteVersionAndFeatures(false);

  // Isolate快照的根为object store
  serializer.WriteIsolateSnapshot(num_base_objects, object_store);
  serializer.FillHeader(serializer.kind());
  clustered_isolate_size_ = serializer.bytes_written();

  if (Snapshot::IncludesCode(kind_)) {
    isolate_image_writer_-&amp;gt;SetProfileWriter(profile_writer_);
    //[见小节3.4]
    isolate_image_writer_-&amp;gt;Write(serializer.stream(), false);
#if defined(DART_PRECOMPILER)
    isolate_image_writer_-&amp;gt;DumpStatistics();
#endif
    mapped_data_size_ += isolate_image_writer_-&amp;gt;data_size();
    mapped_text_size_ += isolate_image_writer_-&amp;gt;text_size();
    isolate_image_writer_-&amp;gt;ResetOffsets();
    isolate_image_writer_-&amp;gt;ClearProfileWriter();
  }

  // 集群部分 + 直接映射的数据部分
  isolate_snapshot_size_ = serializer.bytes_written();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;37-assemblyimagewriterfinalize&quot;&gt;3.7 AssemblyImageWriter::Finalize&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/image_snapshot.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void AssemblyImageWriter::Finalize() {
#ifdef DART_PRECOMPILER
  dwarf_-&amp;gt;Write();
#endif
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;371-dwarfwrite&quot;&gt;3.7.1 Dwarf.Write&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dwarf.h]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Dwarf : public ZoneAllocated {

  void Write() {
    WriteAbbreviations();
    WriteCompilationUnit();
    WriteLines();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Dwarf数据采用数的形式，其节点称为DIE，每个DIE均以缩写代码开头，并且该缩写描述了该DIE的属性及其表示形式。&lt;/p&gt;

&lt;h2 id=&quot;四-android快照产物生成&quot;&gt;四、 Android快照产物生成&lt;/h2&gt;

&lt;h3 id=&quot;41-dart_createappaotsnapshotasblobs&quot;&gt;4.1 Dart_CreateAppAOTSnapshotAsBlobs&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/runtime/vm/dart_api_impl.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;DART_EXPORT Dart_Handle
Dart_CreateAppAOTSnapshotAsBlobs(uint8_t** vm_snapshot_data_buffer,
                                 intptr_t* vm_snapshot_data_size,
                                 uint8_t** vm_snapshot_instructions_buffer,
                                 intptr_t* vm_snapshot_instructions_size,
                                 uint8_t** isolate_snapshot_data_buffer,
                                 intptr_t* isolate_snapshot_data_size,
                                 uint8_t** isolate_snapshot_instructions_buffer,
                                 intptr_t* isolate_snapshot_instructions_size,
                                 const uint8_t* shared_data,
                                 const uint8_t* shared_instructions) {
#if defined(DART_PRECOMPILER)
  DARTSCOPE(Thread::Current());
  API_TIMELINE_DURATION(T);
  Isolate* I = T-&amp;gt;isolate();
  CHECK_NULL(vm_snapshot_data_buffer);
  CHECK_NULL(vm_snapshot_data_size);
  CHECK_NULL(vm_snapshot_instructions_buffer);
  CHECK_NULL(vm_snapshot_instructions_size);
  CHECK_NULL(isolate_snapshot_data_buffer);
  CHECK_NULL(isolate_snapshot_data_size);
  CHECK_NULL(isolate_snapshot_instructions_buffer);
  CHECK_NULL(isolate_snapshot_instructions_size);

  const void* shared_data_image = NULL;
  if (shared_data != NULL) {
    shared_data_image = Snapshot::SetupFromBuffer(shared_data)-&amp;gt;DataImage();
  }
  const void* shared_instructions_image = shared_instructions;

  TIMELINE_DURATION(T, Isolate, &quot;WriteAppAOTSnapshot&quot;);
  BlobImageWriter vm_image_writer(T, vm_snapshot_instructions_buffer,
                ApiReallocate, 2 * MB, nullptr, nullptr, nullptr);
  BlobImageWriter isolate_image_writer(T, isolate_snapshot_instructions_buffer,
                ApiReallocate, 2 * MB , shared_data_image, shared_instructions_image, nullptr);
  FullSnapshotWriter writer(Snapshot::kFullAOT,
                vm_snapshot_data_buffer, isolate_snapshot_data_buffer,
                ApiReallocate, &amp;amp;vm_image_writer, &amp;amp;isolate_image_writer);
  //[见小节3.1]
  writer.WriteFullSnapshot();
  *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
  *vm_snapshot_instructions_size = vm_image_writer.InstructionsBlobSize();
  *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
  *isolate_snapshot_instructions_size = isolate_image_writer.InstructionsBlobSize();
  return Api::Success();
#endif
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能是将snapshot写入buffer缓存：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;vm_snapshot_data_buffer&lt;/li&gt;
  &lt;li&gt;vm_snapshot_instructions_buffer&lt;/li&gt;
  &lt;li&gt;isolate_snapshot_data_buffer&lt;/li&gt;
  &lt;li&gt;isolate_snapshot_instructions_buffer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;再下一步将这些数据写入文件。&lt;/p&gt;

&lt;h2 id=&quot;附录&quot;&gt;附录&lt;/h2&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;third_party/dart/runtime/
  - bin/gen_snapshot.cc
  - vm/dart_api_impl.cc
  - vm/compiler/aot/precompiler.cc
&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Sat, 21 Sep 2019 21:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/09/21/flutter_gen_snapshot/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/09/21/flutter_gen_snapshot/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>Flutter前端编译frontend_server</title>
        <description>&lt;h2 id=&quot;一概述&quot;&gt;一、概述&lt;/h2&gt;

&lt;p&gt;书接上文&lt;a href=&quot;http://gityuan.com/2019/09/07/flutter_run/&quot;&gt;源码解读Flutter run机制&lt;/a&gt;的第四节 flutter build aot命令将dart源码编译成AOT产物，其主要工作为前端编译器frontend_server和机器码生成，本文先介绍前端编译器frontend_server的工作原理。&lt;/p&gt;

&lt;h3 id=&quot;11-frontend_server命令&quot;&gt;1.1 frontend_server命令&lt;/h3&gt;
&lt;p&gt;KernelCompiler.compile()过程等价于如下命令：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;// 该frontend_server命令 同时适用于Android和iOS
flutter/bin/cache/dart-sdk/bin/dart                                            \
  flutter/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot  \
  --sdk-root flutter/bin/cache/artifacts/engine/common/flutter_patched_sdk/    \
  --strong                                                                     \
  --target=flutter                                                             \
  --aot --tfa                                                                  \
  -Ddart.vm.product=true                                                       \
  --packages .packages                                                         \
  --output-dill /build/app/intermediates/flutter/release/app.dill              \
  --depfile     /build/app/intermediates/flutter/release/kernel_compile.d      \
  --&quot;package&quot; /lib/main.dart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可见，通过dart虚拟机启动frontend_server.dart.snapshot，将dart代码转换成app.dill形式的kernel文件。frontend_server.dart.snapshot入口位于Flutter引擎中的
flutter/frontend_server/bin/starter.dart。&lt;/p&gt;

&lt;h3 id=&quot;12-frontend参数表&quot;&gt;1.2 frontend参数表&lt;/h3&gt;
&lt;p&gt;前端编译器的可选参数：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;参数&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
      &lt;th&gt;默认值&lt;/th&gt;
      &lt;th&gt; &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;aot&lt;/td&gt;
      &lt;td&gt;在AOT模式下运行编译器（启用整个程序转换）&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;tfa&lt;/td&gt;
      &lt;td&gt;在AOT模式下启用全局类型流分析和相关转换&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;train&lt;/td&gt;
      &lt;td&gt;通过示例命令行运行以生成快照&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;incremental&lt;/td&gt;
      &lt;td&gt;以增量模式运行编译器&lt;/td&gt;
      &lt;td&gt;flase&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;link-platform&lt;/td&gt;
      &lt;td&gt;批处理模式，平台kernel文件链接到结果的内核文件&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;embed-source-text&lt;/td&gt;
      &lt;td&gt;源码加入到生成的dill文件，便于得到用于调试的堆栈信息&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;track-widget-creation&lt;/td&gt;
      &lt;td&gt;运行内核转换器来跟踪widgets创建的位置&lt;/td&gt;
      &lt;td&gt;false&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;strong&lt;/td&gt;
      &lt;td&gt;已过时flags&lt;/td&gt;
      &lt;td&gt;true&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;import-dill&lt;/td&gt;
      &lt;td&gt;从已存在的dill文件中引入库&lt;/td&gt;
      &lt;td&gt;null&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;output-dill&lt;/td&gt;
      &lt;td&gt;将生成的dill文件输出路径&lt;/td&gt;
      &lt;td&gt;null&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;output-incremental-dill&lt;/td&gt;
      &lt;td&gt;将生成的增量dill文件输出路径&lt;/td&gt;
      &lt;td&gt;null&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;depfile&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;仅用于批量，输出Ninja的depfile&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;packages&lt;/td&gt;
      &lt;td&gt;用于编译的.packages文件&lt;/td&gt;
      &lt;td&gt;null&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;sdk-root&lt;/td&gt;
      &lt;td&gt;SDK根目录的路径&lt;/td&gt;
      &lt;td&gt;../../out/android_debug/flutter_patched_sdk&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;target&lt;/td&gt;
      &lt;td&gt;确定哪些核心库可用，可取值vm、flutter、flutter_runner、dart_runner&lt;/td&gt;
      &lt;td&gt;vm&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;增量模式运行编译器应该能加快编译速度&lt;/li&gt;
  &lt;li&gt;track-widget-creation、aot、tfa参数的使用场景&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;13-frontend_server执行流程图&quot;&gt;1.3 frontend_server执行流程图&lt;/h3&gt;

&lt;p&gt;（1）&lt;a href=&quot;/img/flutter_compile/SeqAST.jpg&quot;&gt;点击查看大图&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_compile/SeqAST.jpg&quot; alt=&quot;SeqAST&quot; /&gt;&lt;/p&gt;

&lt;p&gt;frontend_server前端编译器将dart代码转换为AST，并生成app.dill文件，其中bytecode生成过程默认是关闭的。&lt;/p&gt;

&lt;p&gt;（2）&lt;a href=&quot;/img/flutter_compile/FlutterComplile.jpg&quot;&gt;点击查看大图&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_compile/FlutterComplile.jpg&quot; alt=&quot;FlutterComplile&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Component的成员变量:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;uriToSource的类型为Map&amp;lt;Uri, Source&amp;gt; ，用于从源文件URI映射到行开始表和源代码。给定一个源文件URI和该文件中的偏移量，就可以转换为该文件中line：column的位置。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;二-源码解读frontend_server&quot;&gt;二、 源码解读frontend_server&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BuildAotCommand.runCommand
  AOTSnapshotter.compileKernel
    KernelCompiler.compile
      frontend_server命令
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;21-startermain&quot;&gt;2.1 starter.main&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/frontend_server/bin/starter.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void main(List&amp;lt;String&amp;gt; args) async {
  final int exitCode = await starter(args);
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;22-serverstarter&quot;&gt;2.2 server.starter&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/frontend_server/lib/server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;int&amp;gt; starter(
    List&amp;lt;String&amp;gt; args, {
      frontend.CompilerInterface compiler,
      Stream&amp;lt;List&amp;lt;int&amp;gt;&amp;gt; input,
      StringSink output,
    }) async {
  ...
  //解析参数 [见小节2.2.1]
  ArgResults options = frontend.argParser.parse(args);
  //创建前端编译器实例对象
  compiler ??= new _FlutterFrontendCompiler(output,
      trackWidgetCreation: options['track-widget-creation'],
      unsafePackageSerialization: options['unsafe-package-serialization']);

  if (options.rest.isNotEmpty) {
    //解析命令行的剩余参数 [见小节2.3]
    return await compiler.compile(options.rest[0], options) ? 0 : 254;
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要工作：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;解析KernelCompiler.compile()方法中传递过来的参数，参数表小节[1.2]&lt;/li&gt;
  &lt;li&gt;创建前端编译器实例对象_FlutterFrontendCompiler；&lt;/li&gt;
  &lt;li&gt;执行编译操作；&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;23-_flutterfrontendcompilercompile&quot;&gt;2.3 _FlutterFrontendCompiler.compile&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/frontend_server/lib/server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _FlutterFrontendCompiler implements frontend.CompilerInterface{
  final frontend.CompilerInterface _compiler;

  _FlutterFrontendCompiler(StringSink output,
      {bool trackWidgetCreation: false, bool unsafePackageSerialization}) :
          //创建编译器对象
          _compiler = new frontend.FrontendCompiler(output,
          transformer: trackWidgetCreation ? new WidgetCreatorTracker() : null,
          unsafePackageSerialization: unsafePackageSerialization);

  Future&amp;lt;bool&amp;gt; compile(String filename, ArgResults options, {IncrementalCompiler generator}) async {
      // filename是入口文件名 [见小节2.4]  
    return _compiler.compile(filename, options, generator: generator);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;创建前端编译器实例对象_FlutterFrontendCompiler，其内部有一个重要的成员变量frontend.FrontendCompiler，该对象主要是在FrontendCompile功能的基础之上编译中添加了一个widgetCreatorTracker的内核转换器，所以核心工作都是交由FrontendCompiler来执行。&lt;/p&gt;

&lt;h3 id=&quot;24-frontendcompilercompile&quot;&gt;2.4 FrontendCompiler.compile&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/frontend_server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class FrontendCompiler implements CompilerInterface {

  Future&amp;lt;bool&amp;gt; compile(String entryPoint, ArgResults options, {IncrementalCompiler generator,}) async {
    _options = options;
    _fileSystem = createFrontEndFileSystem(options['filesystem-scheme'], options['filesystem-root']);
    //源码入口函数名，也就是lib/main.dart
    _mainSource = _getFileOrUri(entryPoint);
    _kernelBinaryFilenameFull = _options['output-dill'] ?? '$entryPoint.dill';
    _kernelBinaryFilenameIncremental = _options['output-incremental-dill'] ??
        (_options['output-dill'] != null
            ? '${_options['output-dill']}.incremental.dill'
            : '$entryPoint.incremental.dill');
    _kernelBinaryFilename = _kernelBinaryFilenameFull;
    _initializeFromDill = _options['initialize-from-dill'] ?? _kernelBinaryFilenameFull;
    final String boundaryKey = new Uuid().generateV4();
    _outputStream.writeln('result $boundaryKey');
    final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
    final String platformKernelDill = options['platform'] ?? 'platform_strong.dill';
    ...

    Component component;
    if (options['incremental']) {
      _compilerOptions = compilerOptions;
      setVMEnvironmentDefines(environmentDefines, _compilerOptions);

      _compilerOptions.omitPlatform = false;
      _generator = generator ?? _createGenerator(new Uri.file(_initializeFromDill));
      await invalidateIfInitializingFromDill();
      component = await _runWithPrintRedirection(() =&amp;gt; _generator.compile());
    } else {
      ...
      // [见小节2.5]
      component = await _runWithPrintRedirection(() =&amp;gt; compileToKernel(
          _mainSource, compilerOptions,
          aot: options['aot'],
          useGlobalTypeFlowAnalysis: options['tfa'],
          environmentDefines: environmentDefines));
    }
    if (component != null) {
      if (transformer != null) {
        transformer.transform(component);
      }
      //[见小节2.10] 写入dill文件
      await writeDillFile(component, _kernelBinaryFilename,
          filterExternal: importDill != null);

      await _outputDependenciesDelta(component);
      final String depfile = options['depfile'];
      if (depfile != null) {
        await writeDepfile(compilerOptions.fileSystem, component,
            _kernelBinaryFilename, depfile);
      }
      _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
    }
    return errors.isEmpty;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;执行compileToKernel，将dart转换为kernel文件，也就是中间语言文件；&lt;/li&gt;
  &lt;li&gt;再将中间数据写入app.dill文件&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;25-compiletokernel&quot;&gt;2.5 compileToKernel&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/kernel_front_end.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;Component&amp;gt; compileToKernel(Uri source, CompilerOptions options,
    {bool aot: false,
    bool useGlobalTypeFlowAnalysis: false,
    Map&amp;lt;String, String&amp;gt; environmentDefines,
    bool genBytecode: false,
    bool emitBytecodeSourcePositions: false,
    bool emitBytecodeAnnotations: false,
    bool dropAST: false,
    bool useFutureBytecodeFormat: false,
    bool enableAsserts: false,
    bool enableConstantEvaluation: true,
    bool useProtobufTreeShaker: false}) async {
  //替代错误处理程序以检测是否存在编译错误
  final errorDetector = new ErrorDetector(previousErrorHandler: options.onDiagnostic);
  options.onDiagnostic = errorDetector;

  setVMEnvironmentDefines(environmentDefines, options);
  //将dart代码转换为component对象 [见小节2.6]
  final component = await kernelForProgram(source, options);

  if (aot &amp;amp;&amp;amp; component != null) {
    // 执行全局转换器 [见小节2.7]
    await _runGlobalTransformations(
        source,
        options,
        component,
        useGlobalTypeFlowAnalysis,
        environmentDefines,
        enableAsserts,
        enableConstantEvaluation,
        useProtobufTreeShaker,
        errorDetector);
  }

  if (genBytecode &amp;amp;&amp;amp; !errorDetector.hasCompilationErrors &amp;amp;&amp;amp; component != null) {
    //生成字节码，genBytecode默认为false，不执行该操作 [见小节2.8]
    await runWithFrontEndCompilerContext(source, options, component, () {
      generateBytecode(component,
          emitSourcePositions: emitBytecodeSourcePositions,
          emitAnnotations: emitBytecodeAnnotations,
          useFutureBytecodeFormat: useFutureBytecodeFormat,
          environmentDefines: environmentDefines);
    });
    if (dropAST) {
      new ASTRemover(component).visitComponent(component);
    }
  }

  //恢复错误处理程序
  options.onDiagnostic = errorDetector.previousErrorHandler;
  return component;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;kernelForProgram：将dart代码转换为component对象；&lt;/li&gt;
  &lt;li&gt;_runGlobalTransformations：执行全局转换器；&lt;/li&gt;
  &lt;li&gt;generateBytecode：默认genBytecode为false，AST不生成kernel字节码&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;26-kernelforprogram&quot;&gt;2.6 kernelForProgram&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/front_end/lib/src/api_prototype/kernel_generator.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;CompilerResult&amp;gt; kernelForProgram(
    Uri source, CompilerOptions options) async {
  return (await kernelForProgramInternal(source, options));
}

Future&amp;lt;CompilerResult&amp;gt; kernelForProgramInternal(
    Uri source, CompilerOptions options,
    {bool retainDataForTesting: false}) async {
  var pOptions = new ProcessedOptions(options: options, inputs: [source]);
  return await CompilerContext.runWithOptions(pOptions, (context) async {
    //生成component [见小节2.6.1]
    var component = (await generateKernelInternal())?.component;
    if (component == null) return null;
    // 输入source应该是包含main方法的脚步，否则将报告错误
    if (component.mainMethod == null) {
      context.options.report(
          messageMissingMain.withLocation(source, -1, noLength),
          Severity.error);
      return null;
    }
    return component;
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法的主要功能是将整个dart程序代码生成component对象。编译整个程序，生成程序的内核表示，该程序的主库位于给定的源码。 给定包含main方法的文件的Uri，通过该函数的import, export, part声明来发现整个程序，并将结果转换为Dart Kernel格式。 需要注意的是，当[options]中的compileSdk=true，则生成的组件将包含SDK代码。&lt;/p&gt;

&lt;p&gt;Component的成员变量libraries，记录所有的lib库，包括app源文件、package以及三方库。每个Library对象会有Class、Field、procedure等组成。&lt;/p&gt;

&lt;h4 id=&quot;261-generatekernelinternal&quot;&gt;2.6.1 generateKernelInternal&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/front_end/lib/src/kernel_generator_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;CompilerResult&amp;gt; generateKernelInternal(
    {bool buildSummary: false,
    bool buildComponent: true,
    bool truncateSummary: false}) async {
  var options = CompilerContext.current.options;
  var fs = options.fileSystem;
  Loader sourceLoader;
  return withCrashReporting&amp;lt;CompilerResult&amp;gt;(() async {
    UriTranslator uriTranslator = await options.getUriTranslator();

    var dillTarget = new DillTarget(options.ticker, uriTranslator, options.target);
    ...
    await dillTarget.buildOutlines();

    //创建KernelTarget
    var kernelTarget = new KernelTarget(fs, false, dillTarget, uriTranslator);
    sourceLoader = kernelTarget.loader;
    kernelTarget.setEntryPoints(options.inputs);
    Component summaryComponent = await kernelTarget.buildOutlines(nameRoot: nameRoot);

    if (buildSummary) {
      ...
    }

    Component component;
    if (buildComponent) {
      //[见小节2.6.2]
      component = await kernelTarget.buildComponent(verify: options.verify);
    }
    ...
    return new InternalCompilerResult(
        summary: summary,
        component: component,
        classHierarchy:
            includeHierarchyAndCoreTypes ? kernelTarget.loader.hierarchy : null,
        coreTypes:
            includeHierarchyAndCoreTypes ? kernelTarget.loader.coreTypes : null,
        deps: new List&amp;lt;Uri&amp;gt;.from(CompilerContext.current.dependencies),
        kernelTargetForTesting: retainDataForTesting ? kernelTarget : null);
    }, () =&amp;gt; sourceLoader?.currentUriForCrashReporting ?? options.inputs.first);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;262-buildcomponent&quot;&gt;2.6.2 buildComponent&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class KernelTarget extends TargetImplementation {

  Component component;  //成员变量--组件

  Future&amp;lt;Component&amp;gt; buildComponent({bool verify: false}) async {
    if (loader.first == null) return null;
    return withCrashReporting&amp;lt;Component&amp;gt;(() async {
      //[见小节2.6.3]
      await loader.buildBodies();
      finishClonedParameters();
      loader.finishDeferredLoadTearoffs();
      loader.finishNoSuchMethodForwarders();
      List&amp;lt;SourceClassBuilder&amp;gt; myClasses = collectMyClasses();
      loader.finishNativeMethods();
      loader.finishPatchMethods();
      finishAllConstructors(myClasses);
      runBuildTransformations();

      if (verify) this.verify();
      installAllComponentProblems(loader.allComponentProblems);
      return component;
    }, () =&amp;gt; loader?.currentUriForCrashReporting);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;KernelTarget的component记录整个dart代码的各种信息。&lt;/p&gt;

&lt;h4 id=&quot;263-buildbodies&quot;&gt;2.6.3 buildBodies&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/front_end/lib/src/fasta/loader.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;Null&amp;gt; buildBodies() async {
  for (LibraryBuilder library in builders.values) {
    if (library.loader == this) {
      currentUriForCrashReporting = library.uri;
      //[见小节2.6.4]
      await buildBody(library);
    }
  }
  currentUriForCrashReporting = null;
  logSummary(templateSourceBodySummary);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处的loader为SourceLoader，是在KernelTarget对象创建过程初始化的。&lt;/p&gt;

&lt;h4 id=&quot;264-buildbody&quot;&gt;2.6.4 buildBody&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/front_end/lib/src/fasta/source/source_loader.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class SourceLoader extends Loader&amp;lt;Library&amp;gt; {

  Future&amp;lt;Null&amp;gt; buildBody(LibraryBuilder library) async {
    if (library is SourceLibraryBuilder) {
      //词法分析
      Token tokens = await tokenize(library, suppressLexicalErrors: true);
      DietListener listener = createDietListener(library);
      DietParser parser = new DietParser(listener);
      //语法分析
      parser.parseUnit(tokens);
      for (SourceLibraryBuilder part in library.parts) {
        if (part.partOfLibrary != library) {
          // part部分包含在多个库中，此处跳过
          continue;
        }
        Token tokens = await tokenize(part);
        if (tokens != null) {
          listener.uri = part.fileUri;
          listener.partDirectiveIndex = 0;
          parser.parseUnit(tokens);
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要工作：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;词法分析tokenize：对库中dart源码，根据一定的词法规则解析成词法单元tokens；&lt;/li&gt;
  &lt;li&gt;语法分析parser：对tokens根据Dart语法规则解析成抽象语法树；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;说明，这个过程采用两次标记源文件，以保持较低的内存使用率。 这是第二次，第一次是在上面的[buildOutline]中，所以这抑制词法错误。&lt;/p&gt;

&lt;h3 id=&quot;27-_runglobaltransformations&quot;&gt;2.7 _runGlobalTransformations&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/kernel_front_end.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future _runGlobalTransformations(
    Uri source,
    CompilerOptions compilerOptions,
    Component component,
    bool useGlobalTypeFlowAnalysis,
    Map&amp;lt;String, String&amp;gt; environmentDefines,
    bool enableAsserts,
    bool enableConstantEvaluation,
    bool useProtobufTreeShaker,
    ErrorDetector errorDetector) async {
  if (errorDetector.hasCompilationErrors) return;

  final coreTypes = new CoreTypes(component);
  _patchVmConstants(coreTypes);

  //mixin应用在前端创建mixin应用时，所有后端(以及从一开始就进行的所有转换)能都受益于mixin重复数据删除。
  //AOT除外， JIT构建情况下，都需要运行此转换
  mixin_deduplication.transformComponent(component);

  if (enableConstantEvaluation) {
    await _performConstantEvaluation(source, compilerOptions, component,
        coreTypes, environmentDefines, enableAsserts);

    if (errorDetector.hasCompilationErrors) return;
  }

  if (useGlobalTypeFlowAnalysis) {
    globalTypeFlow.transformComponent(
        compilerOptions.target, coreTypes, component);
  } else {
    devirtualization.transformComponent(coreTypes, component);
    no_dynamic_invocations_annotator.transformComponent(component);
  }

  if (useProtobufTreeShaker) {
    if (!useGlobalTypeFlowAnalysis) {
      throw 'Protobuf tree shaker requires type flow analysis (--tfa)';
    }

    protobuf_tree_shaker.removeUnusedProtoReferences(
        component, coreTypes, null);

    globalTypeFlow.transformComponent(
        compilerOptions.target, coreTypes, component);
  }

  // 避免通过从平台文件读取重新计算CSA
  void ignoreAmbiguousSupertypes(cls, a, b) {}
  final hierarchy = new ClassHierarchy(component,
      onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
  call_site_annotator.transformLibraries(
      component, component.libraries, coreTypes, hierarchy);

  // 不确定gen_snapshot是否要进行混淆处理，但是如果这样做，则需要混淆处理禁止。
  obfuscationProhibitions.transformComponent(component, coreTypes);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;执行混淆等转换工作&lt;/p&gt;

&lt;h3 id=&quot;28-runwithfrontendcompilercontext&quot;&gt;2.8 runWithFrontEndCompilerContext&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/kernel_front_end.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;T&amp;gt; runWithFrontEndCompilerContext&amp;lt;T&amp;gt;(Uri source,
    CompilerOptions compilerOptions, Component component, T action()) async {
  final processedOptions =
      new ProcessedOptions(options: compilerOptions, inputs: [source]);

  //在上下文中运行，则可以获取uri源的tokens
  return await CompilerContext.runWithOptions(processedOptions,
      (CompilerContext context) async {
    // 为了使fileUri / fileOffset-&amp;gt;行/列映射，则需要预填充映射。
    context.uriToSource.addAll(component.uriToSource);
    //此处action对应的是generateBytecode()方法 [见小节2.8.1]
    return action();
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;generateBytecode
  BytecodeGenerator.visitLibrary(Library node)
    visitList(node.procedures, BytecodeGenerator);
      Procedure.accept(BytecodeGenerator);
        BytecodeGenerator.visitProcedure(Procedure);
          BytecodeGenerator.defaultMember(Procedure)
            _genxxx
              asm.emitPush
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;third_party/dart/pkg/vm/lib/bytecode/dbc.dart 中定义很多指令&lt;/p&gt;

&lt;h4 id=&quot;281-generatebytecode&quot;&gt;2.8.1 generateBytecode&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/bytecode/gen_bytecode.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;
void generateBytecode(
  ast.Component component, {
  bool emitSourcePositions: false,
  bool emitAnnotations: false,
  bool omitAssertSourcePositions: false,
  bool useFutureBytecodeFormat: false,
  Map&amp;lt;String, String&amp;gt; environmentDefines: const &amp;lt;String, String&amp;gt;{},
  ErrorReporter errorReporter,
  List&amp;lt;Library&amp;gt; libraries,
}) {
  final coreTypes = new CoreTypes(component);
  void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
  final hierarchy = new ClassHierarchy(component,
      onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
  final typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
  final constantsBackend = new VmConstantsBackend(coreTypes);
  final errorReporter = new ForwardConstantEvaluationErrors();
  //从component获取libraries
  libraries ??= component.libraries;
  //创建字节码生成器对象
  final bytecodeGenerator = new BytecodeGenerator(
      component,
      coreTypes,
      hierarchy,
      typeEnvironment,
      constantsBackend,
      environmentDefines,
      emitSourcePositions,
      emitAnnotations,
      omitAssertSourcePositions,
      useFutureBytecodeFormat,
      errorReporter);
  for (var library in libraries) {
    //[见小节2.8.2]
    bytecodeGenerator.visitLibrary(library);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;遍历component中的所有libraries。&lt;/p&gt;

&lt;h4 id=&quot;282-visitlibrary&quot;&gt;2.8.2 visitLibrary&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/bytecode/gen_bytecode.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class BytecodeGenerator extends RecursiveVisitor&amp;lt;Null&amp;gt; {

  visitLibrary(Library node) {
    if (node.isExternal) {
      return;
    }
    //对于class的visit会调用到下方的visitClass
    visitList(node.classes, this);
    //初始化fieldDeclarations和functionDeclarations来记录类的字段和方法
    startMembers();
    // [见小节2.8.3]
    visitList(node.procedures, this);
    visitList(node.fields, this);
    endMembers(node);
  }

  visitClass(Class node) {
    startMembers();
    visitList(node.constructors, this);
    visitList(node.procedures, this);
    visitList(node.fields, this);
    endMembers(node);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;通过visitList来访问库中的classes，procedures，fields。
    &lt;ul&gt;
      &lt;li&gt;先访问类中的构造函数constructors、方法procedures以及字段fields；&lt;/li&gt;
      &lt;li&gt;再访问库中不属于任何类的一些方法和字段；&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;fieldDeclarations和functionDeclarations来记录类的字段和方法，最终保存在bytecodeComponent的成员变量members；&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;283-visitlist&quot;&gt;2.8.3 visitList&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/kernel/lib/ast.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void visitList(List&amp;lt;Node&amp;gt; nodes, Visitor visitor) {
  for (int i = 0; i &amp;lt; nodes.length; ++i) {
    // [见小节2.8.4]
    nodes[i].accept(visitor);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;此处的nodes，可以是classes，constructors，procedures或者fields&lt;/li&gt;
  &lt;li&gt;此处的visitor，便是BytecodeGenerator&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;284-accept&quot;&gt;2.8.4 accept&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/kernel/lib/ast.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Procedure extends Member {
  accept(MemberVisitor v) =&amp;gt; v.visitProcedure(this);
}

class Field extends Member {
  R accept&amp;lt;R&amp;gt;(MemberVisitor&amp;lt;R&amp;gt; v) =&amp;gt; v.visitField(this);
}

class Constructor extends Member {
  R accept&amp;lt;R&amp;gt;(MemberVisitor&amp;lt;R&amp;gt; v) =&amp;gt; v.visitConstructor(this);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处的v是BytecodeGenerator，而BytecodeGenerator间接继承于TreeVisitor，在TreeVisitor由大量的visitXXX()方法，最终都是调用到defaultMember()，如下所示。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class TreeVisitor&amp;lt;R&amp;gt; {
  // [见小节2.8.5]
  R visitConstructor(Constructor node) =&amp;gt; defaultMember(node);
  R visitProcedure(Procedure node) =&amp;gt; defaultMember(node);
  R visitField(Field node) =&amp;gt; defaultMember(node);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;285-defaultmember&quot;&gt;2.8.5 defaultMember&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/bytecode/gen_bytecode.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;defaultMember(Member node) {
  // 当该方法表示重定向工厂构造函数，并且没有可运行的主体，则直接返回
  if (node is Procedure &amp;amp;&amp;amp; node.isRedirectingFactoryConstructor) {
    return;
  }
  try {
    bool hasCode = false;
    start(node);
    //字段类型
    if (node is Field) {  
      if (hasInitializerCode(node)) {
        hasCode = true;
        if (node.isConst) {
          _genPushConstExpr(node.initializer);
        } else {
          _generateNode(node.initializer);
        }
        _genReturnTOS();
      }
      //方法类型
    } else if ((node is Procedure &amp;amp;&amp;amp; !node.isRedirectingFactoryConstructor) ||
        (node is Constructor)) {
      if (!node.isAbstract) {
        hasCode = true;
        if (node is Constructor) {
          _genConstructorInitializers(node);
        }
        if (node.isExternal) {
          final String nativeName = getExternalName(node);
          if (nativeName != null) {
            _genNativeCall(nativeName);
          } else {
            asm.emitPushNull();
          }
        } else {
          _generateNode(node.function?.body);
          // 如果无法访问此字节码，则BytecodeAssembler会将其消除。
          asm.emitPushNull();
        }
        _genReturnTOS();
      }
    } else {
      throw 'Unexpected member ${node.runtimeType} $node';
    }
    end(node, hasCode);
  } on BytecodeLimitExceededException {
    // 不生成字节码，回滚到内核语法树AST
    hasErrors = true;
    end(node, false);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能是 根据node类型：字段、方法或者构造方法，则生成相应的汇编指令。 这里会有很多_genXXX()方法，最终是调用asm.emitXXX()方法，
此处的asm的数据类型为BytecodeAssembler。 接下来以emitPushNull为例子，继续往下说。&lt;/p&gt;

&lt;h4 id=&quot;286-emitpushnull&quot;&gt;2.8.6 emitPushNull&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/bytecode/assembler.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class BytecodeAssembler {

  final List&amp;lt;int&amp;gt; bytecode = new List&amp;lt;int&amp;gt;();
  final Uint32List _encodeBufferIn;
  final Uint8List _encodeBufferOut;

  void emitPushNull() {
    emitWord(_encode0(Opcode.kPushNull));
  }

  void emitWord(int word) {
    if (isUnreachable) {
      return;
    }
    _encodeBufferIn[0] = word;  //opcode写入_encodeBufferIn
    bytecode.addAll(_encodeBufferOut);
  }
  //将操作码转换整型
  int _encode0(Opcode opcode) =&amp;gt; _uint8(opcode.index);
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可见，所有的字节码信息最终都写入到BytecodeAssembler的bytecode列表。另外，Opcode操作码位于dbc.dart，里面定义了各种操作码。&lt;/p&gt;

&lt;h3 id=&quot;29-writedillfile&quot;&gt;2.9 writeDillFile&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/vm/lib/frontend_server.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;writeDillFile(Component component, String filename,
    {bool filterExternal: false}) async {
  final IOSink sink = new File(filename).openWrite();
  final BinaryPrinter printer = filterExternal
      ? new LimitedBinaryPrinter(
          sink, (lib) =&amp;gt; !lib.isExternal, true /* excludeUriToSource */)
      : printerFactory.newBinaryPrinter(sink);

  component.libraries.sort((Library l1, Library l2) {
    return &quot;${l1.fileUri}&quot;.compareTo(&quot;${l2.fileUri}&quot;);
  });

  component.computeCanonicalNames();
  for (Library library in component.libraries) {
    library.additionalExports.sort((Reference r1, Reference r2) {
      return &quot;${r1.canonicalName}&quot;.compareTo(&quot;${r2.canonicalName}&quot;);
    });
  }
  if (unsafePackageSerialization == true) {
    writePackagesToSinkAndTrimComponent(component, sink);
  }
  //[见小节2.9.1]
  printer.writeComponentFile(component);
  await sink.close();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;再回到[小节2.4]，执行完compileToKernel()后开始执行writeDillFile，该方法主要功能便是将component内容写入app.dill文件。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;component：是指compileToKernel()方法执行后得到的，记录dart代码中类、方法、字段等所有相关信息&lt;/li&gt;
  &lt;li&gt;filename：是指前面传递–output-dill参数值，也就是app.dill&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;291-writecomponentfile&quot;&gt;2.9.1 writeComponentFile&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/pkg/kernel/lib/binary/ast_to_binary.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void writeComponentFile(Component component) {
  computeCanonicalNames(component);
  final componentOffset = getBufferOffset();
  writeUInt32(Tag.ComponentFile);
  writeUInt32(Tag.BinaryFormatVersion);
  writeListOfStrings(component.problemsAsJson);
  indexLinkTable(component);
  _collectMetadata(component);
  if (_metadataSubsections != null) {
    // 将asm.bytecode写入文件
    _writeNodeMetadataImpl(component, componentOffset);
  }
  libraryOffsets = &amp;lt;int&amp;gt;[];
  CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
  if (main != null) {
    checkCanonicalName(main);
  }
  writeLibraries(component);
  writeUriToSource(component.uriToSource);
  writeLinkTable(component);
  _writeMetadataSection(component);
  writeStringTable(stringIndexer);
  writeConstantTable(_constantIndexer);
  writeComponentIndex(component, component.libraries);

  _flush();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这便完成的kernel编译以及文件生成过程。&lt;/p&gt;

&lt;h2 id=&quot;附录&quot;&gt;附录&lt;/h2&gt;

&lt;p&gt;本文相关源码flutter engine&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;flutter/frontend_server/
  - bin/starter.dart
  - lib/server.dart

third_party/dart/pkg/
  - vm/lib/
    - frontend_server.dart
    - kernel_front_end.dart
    - bytecode/gen_bytecode.dart
    - bytecode/assembler.dart
  - front_end/lib/
    - src/api_prototype/kernel_generator.dart
    - src/kernel_generator_impl.dart
    - src/fasta/kernel/kernel_target.dart
    - src/fasta/loader.dart
    - src/fasta/source/source_loader.dart
  - kernel/lib/
    - ast.dart
    - binary/ast_to_binary.dart
&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Sat, 14 Sep 2019 21:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/09/14/flutter_frontend_server/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/09/14/flutter_frontend_server/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>源码解读Flutter run机制</title>
        <description>&lt;h2 id=&quot;一解读flutter-run命令&quot;&gt;一、解读flutter run命令&lt;/h2&gt;

&lt;h3 id=&quot;11-初识flutter-run&quot;&gt;1.1 初识flutter run&lt;/h3&gt;

&lt;h4 id=&quot;111-ide运行&quot;&gt;1.1.1 IDE运行&lt;/h4&gt;
&lt;p&gt;编写完flutter代码后，一定离不开运行flutter应用。比如Android Studio可点击如下按钮来执行&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_command/ide_flutter_run.png&quot; alt=&quot;ide_flutter_run&quot; /&gt;&lt;/p&gt;

&lt;p&gt;该命令默认是采用debug模式，如果需要运行release模式，可以在IDE选择中的Run-&amp;gt;Configurations的Additional arguments里面加上–release参数&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_command/ide_run_config.png&quot; alt=&quot;ide_run_config&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;112-命令行运行&quot;&gt;1.1.2 命令行运行&lt;/h4&gt;
&lt;p&gt;既然运行应用是通过调用flutter run命令该命令对Android或者iOS设备是通用的，那么下面直接用命令方式来运行。&lt;/p&gt;

&lt;p&gt;1）flutter run命令用于编译打包生成APP，然后安装到已连接设备上，并启动运行该APP的过程。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_command/flutter_demo_debug.png&quot; alt=&quot;flutter_demo_debug&quot; /&gt;&lt;/p&gt;

&lt;p&gt;以Android为例，利用gradle来编译打包，最终apk产物位于/build/app/outputs/apk/debug/app-debug.apk。当flutter run命令后面不带任何参数默认采用的是debug模式，从上图可以看到APP右上角会带有DEBUG标识，对于非DEBUG模式则右上角不会有任何标识。当需要运行release模式，可运行命令：flutter run –release。&lt;/p&gt;

&lt;p&gt;2）当调试性能(需要用到timeline)，且修改本地Flutter引擎代码，则采用profile模式，运行命令：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;flutter run --profile --disable-service-auth-codes --local-engine-src-path=&amp;lt;FLUTTER_ROOT&amp;gt;/engine/src --local-engine android_profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_command/flutter_run_profile_log.png&quot; alt=&quot;flutter_run_profile_log&quot; /&gt;&lt;/p&gt;

&lt;p&gt;从上图可以看出这是运行在Android设备上的profile模式，利用Gradle来构建APK，位于工程根目录下/build/app/outputs/apk/profile/app-profile.apk，安装到手机后并通过am start来启动该应用。对于Profile模式，启动Observatory调试器，可通过127.0.0.1:xxx地址，打开网页版性能分析工具Observatory，其中包含有timeline工具，类似于Android的systrace。&lt;/p&gt;

&lt;h3 id=&quot;12-解读flutter-run参数&quot;&gt;1.2 解读flutter run参数&lt;/h3&gt;
&lt;h4 id=&quot;121-参数表&quot;&gt;1.2.1 参数表&lt;/h4&gt;

&lt;p&gt;通过前面会发现，flutter run后面可以跟不同的参数[arguments]，具体有哪些参数如下所示：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;arguments&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;–debug&lt;/td&gt;
      &lt;td&gt;调试版本，这是默认模式&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–profile&lt;/td&gt;
      &lt;td&gt;profile版本&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–release&lt;/td&gt;
      &lt;td&gt;发布版本&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–target-platform&lt;/td&gt;
      &lt;td&gt;指定app运行的目标平台，比如android-arm/android-arm64，iOS平台不可用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–target=&lt;path&gt;&lt;/path&gt;&lt;/td&gt;
      &lt;td&gt;主入口，默认值lib/main.dart&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–observatory-port&lt;/td&gt;
      &lt;td&gt;指定observatory端口，默认为0（随机生成可用端口）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–disable-service-auth-codes&lt;/td&gt;
      &lt;td&gt;关闭observatory服务鉴权&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–trace-startup&lt;/td&gt;
      &lt;td&gt;跟踪应用启动/退出，并保存trace到文件&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–trace-skia&lt;/td&gt;
      &lt;td&gt;跟踪skia，用于调试GPU线程&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–trace-systrace&lt;/td&gt;
      &lt;td&gt;转为systrace，适用于Android/Fuchsia&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–dump-skp-on-shader-compilation&lt;/td&gt;
      &lt;td&gt;转储触发着色器编译的skp，默认关闭&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–verbose-system-logs&lt;/td&gt;
      &lt;td&gt;包括来自flutter引擎的详细日志记录&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–enable-software-rendering&lt;/td&gt;
      &lt;td&gt;开启软件渲染，默认采用OpenGL或者Vulkan&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–skia-deterministic-rendering&lt;/td&gt;
      &lt;td&gt;确定性采用skia渲染&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–no-hot&lt;/td&gt;
      &lt;td&gt;可关闭热重载，默认是开启&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–start-paused&lt;/td&gt;
      &lt;td&gt;应用启动后暂停&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–local-engine-src-path&lt;/td&gt;
      &lt;td&gt;指定本地引擎源码路径，比如xxx/engine/src&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;–local-engine&lt;/td&gt;
      &lt;td&gt;指定本地引擎类型，比如android_profile&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;对于flutter 1.5及以上的版本，抓取timeline报错的情况下，可采用以下两个方案之一：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;//方案1：关闭鉴权
flutter run --disable-service-auth-codes
//方案2：对于已安装应用，直接运行
adb shell am start -a android.intent.action.RUN -f 0x20000000 --ez enable-background-compilation true --ez enable-dart-profiling true --ez disable-service-auth-codes true --ez trace-skia true com.gityuan.flutterdemo/.MainActivity
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果不确定该应用的activity名，可以通过以下命令获取：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;adb shell dumpsys SurfaceFlinger --list  //方式一
adb shell dumpsys activity a -p io.flutter.demo.gallery //方式二
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;122-gradle参数说明&quot;&gt;1.2.2 gradle参数说明&lt;/h4&gt;

&lt;p&gt;flutter run构建应用的过程，对于Android用到了gradle，下面列举gradle的参数。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;参数&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
      &lt;th&gt; &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;PlocalEngineOut&lt;/td&gt;
      &lt;td&gt;引擎产物&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ptarget&lt;/td&gt;
      &lt;td&gt;取值lib/main.dart&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ptrack-widget-creation&lt;/td&gt;
      &lt;td&gt;默认为false&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pcompilation-trace-file&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ppatch&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pextra-front-end-options&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pextra-gen-snapshot-options&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pfilesystem-roots&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pfilesystem-scheme&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pbuild-shared-library&lt;/td&gt;
      &lt;td&gt;是否采取共享库&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ptarget-platform&lt;/td&gt;
      &lt;td&gt;目标平台&lt;/td&gt;
      &lt;td&gt;=&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;123-build-aot参数说明&quot;&gt;1.2.3 build aot参数说明&lt;/h4&gt;
&lt;p&gt;gradle参数说明会传递到build aot过程，其对应参数说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;-output-dir：指定aot产物输出路径，缺省默认等于“build/aot”；&lt;/li&gt;
  &lt;li&gt;-target：指定应用的主函数，缺省默认等于“lib/main.dart”；&lt;/li&gt;
  &lt;li&gt;-target-platform：指定目标平台，可取值有android-arm，android-arm64，android-x64, android-x86，ios， darwin-linux_x64， linux-x64，web；&lt;/li&gt;
  &lt;li&gt;-ios-arch：指定ios架构类型，可取值有arm64，armv7，仅用于iOS；&lt;/li&gt;
  &lt;li&gt;-build-shared-library：指定是否构建共享库，仅用于Android；iOS强制为false；&lt;/li&gt;
  &lt;li&gt;-release：指定编译模式，可取值有debug, profile, release, dynamicProfile, dynamicRelease；&lt;/li&gt;
  &lt;li&gt;-extra-front-end-options：指定用于编译kernel的可选参数&lt;/li&gt;
  &lt;li&gt;–extra-gen-snapshot-options：指定用于构建AOT快照的可选参数&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;也就是说执行flutter build aot必须指定的参数是target-platform和release参数。&lt;/p&gt;

&lt;h3 id=&quot;13-aot产物命令&quot;&gt;1.3 AOT产物命令&lt;/h3&gt;

&lt;p&gt;产物生成分为Android和iOS产物&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Android AOT产物/build/app/intermediates/flutter/release/目录，最终安装到Android手机的是/build/app/outputs/release/app-release.apk&lt;/li&gt;
  &lt;li&gt;iOS AOT产物位于build/aot目录，最终安装到iOS手机是build/ios/iphoneos/Runner.app&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;131-android-aot产物生成命令&quot;&gt;1.3.1 Android AOT产物生成命令&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;// build aot命令
flutter build aot                                         \
  --suppress-analytics                                    \
  --quiet                                                 \
  --target=lib/main.dart                                  \
  --output-dir=build/app/intermediates/flutter/release    \
  --target-platform=android-arm                           \
  --release                                               \
  --extra-gen-snapshot-options=&quot;--print-snapshot-sizes&quot;                                        
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;132-ios-aot产物生成命令&quot;&gt;1.3.2 iOS AOT产物生成命令&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;// build aot命令
flutter build aot         \
  --suppress-analytics    \
  --target=lib/main.dart  \
  --output-dir=build/aot  \
  --target-platform=ios   \
  --ios-arch=arm64        \
  --release               \
  --extra-gen-snapshot-options=&quot;--print-snapshot-sizes&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果需要同时编译32位和64位，则可以设置参数–ios-arch=armv7,arm64。&lt;/p&gt;

&lt;h3 id=&quot;14-flutter-run原理说明&quot;&gt;1.4 flutter run原理说明&lt;/h3&gt;
&lt;p&gt;flutter run过程涉及多个flutter相关命令，其包含关系如下所示：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_command/flutter_run_arch.jpg&quot; alt=&quot;flutter_run_arch&quot; /&gt;&lt;/p&gt;

&lt;p&gt;图解：&lt;/p&gt;

&lt;p&gt;flutter命令的整个过程位于目录flutter/packages/flutter_tools/，对于flutter run命令核心功能包括以下几部分：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;flutter build apk：通过gradle来构建APK，由以下两部分组成：
    &lt;ul&gt;
      &lt;li&gt;flutter build aot，分为如下两个核心过程，该过程详情见下一篇文章&lt;/li&gt;
    &lt;/ul&gt;
    &lt;ul&gt;
      &lt;li&gt;frontend_server前端编译器生成kernel文件&lt;/li&gt;
      &lt;li&gt;gen_snapshot来编译成AOT产物
      - flutter build bundle，将相关文件放入flutter_assets目录&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;通过adb install来安装APK&lt;/li&gt;
  &lt;li&gt;通过adb am start来启动应用&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;整个flutter run的执行流程图，&lt;a href=&quot;/img/flutter_command/flutter_run_interaction.jpg&quot;&gt;点击查看大图&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_command/flutter_run_interaction.jpg&quot; alt=&quot;flutter_run_interaction&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;二源码解读flutter-run命令&quot;&gt;二、源码解读flutter run命令&lt;/h2&gt;

&lt;p&gt;相信有不少人会好奇flutter命令背后的原理，根据文章&lt;a href=&quot;http://gityuan.com/2019/09/01/flutter_tool/&quot;&gt;Flutter tools&lt;/a&gt;可知，对于flutter run命令，那么对应执行的便是RunCommand.runCommand()。这里就以[小节二]中flutter run命令为起点展开，flutter run 命令对应 RunCommand，该命令执行过程中包括以下4个部分组成：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;[小节三] flutter build apk 命令对应 BuildApkCommand&lt;/li&gt;
  &lt;li&gt;[小节四] flutter build aot 命令对应 BuildAotCommand&lt;/li&gt;
  &lt;li&gt;[小节五] flutter build bundle 命令对应 BuildBundleCommand&lt;/li&gt;
  &lt;li&gt;[小节六] flutter install 命令对应 InstallCommand&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;说明以下过程都位于工程flutter/packages/flutter_tools/目录。&lt;/p&gt;

&lt;h3 id=&quot;21-runcommandruncommand&quot;&gt;2.1 RunCommand.runCommand&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/commands/run.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;FlutterCommandResult&amp;gt; runCommand() async {
  // debug模式会默认开启热加载模式，如果不需要则添加参数--no-hot
  final bool hotMode = shouldUseHotMode();
  ...
  //遍历所有已连接设备，runCommand的validateCommand过程会发现所有已连接设备
  for (Device device in devices) {
    final FlutterDevice flutterDevice = await FlutterDevice.create(
      device,
      trackWidgetCreation: argResults['track-widget-creation'],
      dillOutputPath: argResults['output-dill'],
      fileSystemRoots: argResults['filesystem-root'],
      fileSystemScheme: argResults['filesystem-scheme'],
      viewFilter: argResults['isolate-filter'],
      experimentalFlags: expFlags,
      target: argResults['target'],
      buildMode: getBuildMode(),
    );
    flutterDevices.add(flutterDevice);
  }

  ResidentRunner runner;
  final String applicationBinaryPath = argResults['use-application-binary'];
  if (hotMode) {
    runner = HotRunner(
      flutterDevices,
      target: targetFile,
      //创建调试flag的开关
      debuggingOptions: _createDebuggingOptions(),
      benchmarkMode: argResults['benchmark'],
      applicationBinary: applicationBinaryPath == null
          ? null : fs.file(applicationBinaryPath),
      projectRootPath: argResults['project-root'],
      packagesFilePath: globalResults['packages'],
      dillOutputPath: argResults['output-dill'],
      saveCompilationTrace: argResults['train'],
      stayResident: stayResident,
      ipv6: ipv6,
    );
  } else {
    runner = ColdRunner(
      flutterDevices,
      target: targetFile,
      debuggingOptions: _createDebuggingOptions(),
      traceStartup: traceStartup,
      awaitFirstFrameWhenTracing: awaitFirstFrameWhenTracing,
      applicationBinary: applicationBinaryPath == null
          ? null : fs.file(applicationBinaryPath),
      saveCompilationTrace: argResults['train'],
      stayResident: stayResident,
      ipv6: ipv6,
    );
  }
  ...

  // [见小节2.2]
  final int result = await runner.run(
    appStartedCompleter: appStartedTimeRecorder,
    route: route,
    shouldBuild: !runningWithPrebuiltApplication &amp;amp;&amp;amp; argResults['build'],
  );
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;debug模式会默认开启热加载模式，如果不需要则添加参数–no-hot&lt;/li&gt;
  &lt;li&gt;遍历所有已连接设备，发现所有已连接设备&lt;/li&gt;
  &lt;li&gt;通过_createDebuggingOptions来解析flutter run方法传递过来的命令参数&lt;/li&gt;
  &lt;li&gt;根据启动方式是否为热重载来调用相应ResidentRunner的run()来执行，接下来以hot reload为例展开说明。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;22-hotrunnerrun&quot;&gt;2.2 HotRunner.run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/run_hot.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class HotRunner extends ResidentRunner {
  Future&amp;lt;int&amp;gt; run({
    Completer&amp;lt;DebugConnectionInfo&amp;gt; connectionInfoCompleter,
    Completer&amp;lt;void&amp;gt; appStartedCompleter,
    String route,
    bool shouldBuild = true,
  }) async {
    ...
    firstBuildTime = DateTime.now();

    for (FlutterDevice device in flutterDevices) {
      //[见小节2.3]
      final int result = await device.runHot(
        hotRunner: this,
        route: route,
        shouldBuild: shouldBuild,
      );
    }
    //与设备建立连接
    return attach(
      connectionInfoCompleter: connectionInfoCompleter,
      appStartedCompleter: appStartedCompleter,
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;23-flutterdevicerunhot&quot;&gt;2.3 FlutterDevice.runHot&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/resident_runner.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class FlutterDevice {

  Future&amp;lt;int&amp;gt; runHot({HotRunner hotRunner, String route, bool shouldBuild,}) async {
    final bool prebuiltMode = hotRunner.applicationBinary != null;
    final String modeName = hotRunner.debuggingOptions.buildInfo.friendlyModeName;

    final TargetPlatform targetPlatform = await device.targetPlatform;
    package = await ApplicationPackageFactory.instance.getPackageForPlatform(
        targetPlatform, applicationBinary: hotRunner.applicationBinary,
    );
    ...
    //[见小节2.4/2.5] 启动应用
    final Future&amp;lt;LaunchResult&amp;gt; futureResult = device.startApp(
      package,
      mainPath: hotRunner.mainPath,
      debuggingOptions: hotRunner.debuggingOptions,
      platformArgs: platformArgs,
      route: route,
      prebuiltApplication: prebuiltMode,
      usesTerminalUi: hotRunner.usesTerminalUI,
      ipv6: hotRunner.ipv6,
    );
    final LaunchResult result = await futureResult;
    ...
    return 0;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;应用启动过程，这里小节2.4介绍Android，小节2.5是介绍iOS的启动过程。&lt;/p&gt;

&lt;h3 id=&quot;24-androiddevicestartapp&quot;&gt;2.4 AndroidDevice.startApp&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/android_device.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class AndroidDevice extends Device {

  Future&amp;lt;LaunchResult&amp;gt; startApp(
    ApplicationPackage package, {
    String mainPath,
    String route,
    DebuggingOptions debuggingOptions,
    Map&amp;lt;String, dynamic&amp;gt; platformArgs,
    bool prebuiltApplication = false,
    bool usesTerminalUi = true,
    bool ipv6 = false,
  }) async {
    ...
    //获取平台信息arm64/arm/x64/x86
    final TargetPlatform devicePlatform = await targetPlatform;

    if (!prebuiltApplication || androidSdk.licensesAvailable &amp;amp;&amp;amp; androidSdk.latestVersion == null) {
      final FlutterProject project = await FlutterProject.current();
      //通过gradle来构建APK [小节3.2]
      await buildApk(project: project, target: mainPath, buildInfo: buildInfo,);
      //APK已构建，则从中获取应用id(包名)和activity名
      package = await AndroidApk.fromAndroidProject(project.android);
    }
    //通过adb am force-stop来强杀该应用
    await stopApp(package);

    //该方法会installApp()安装APK [小节6.2]
    if (!await _installLatestApp(package))
      return LaunchResult.failed();
    ...

    if (debuggingOptions.debuggingEnabled) {
      //调试模式，开启observatory
      observatoryDiscovery = ProtocolDiscovery.observatory(
        getLogReader(),
        portForwarder: portForwarder,
        hostPort: debuggingOptions.observatoryPort,
        ipv6: ipv6,
      );
    }

    List&amp;lt;String&amp;gt; cmd;
    // 通过adb am start来启动应用
    cmd = adbCommandForDevice(&amp;lt;String&amp;gt;[
      'shell', 'am', 'start',
      '-a', 'android.intent.action.RUN',
      '-f', '0x20000000', // FLAG_ACTIVITY_SINGLE_TOP
      '--ez', 'enable-background-compilation', 'true',
      '--ez', 'enable-dart-profiling', 'true',
    ]);

    if (traceStartup)
      cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'trace-startup', 'true']);
    if (route != null)
      cmd.addAll(&amp;lt;String&amp;gt;['--es', 'route', route]);
    if (debuggingOptions.enableSoftwareRendering)
      cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'enable-software-rendering', 'true']);
    if (debuggingOptions.skiaDeterministicRendering)
      cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'skia-deterministic-rendering', 'true']);
    if (debuggingOptions.traceSkia)
      cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'trace-skia', 'true']);
    if (debuggingOptions.traceSystrace)
      cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'trace-systrace', 'true']);
    if (debuggingOptions.dumpSkpOnShaderCompilation)
      cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'dump-skp-on-shader-compilation', 'true']);
    if (debuggingOptions.debuggingEnabled) {
      if (debuggingOptions.buildInfo.isDebug) {
        cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'enable-checked-mode', 'true']);
        cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'verify-entry-points', 'true']);
      }
      if (debuggingOptions.startPaused)
        cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'start-paused', 'true']);
      if (debuggingOptions.disableServiceAuthCodes)
        cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'disable-service-auth-codes', 'true']);
      if (debuggingOptions.useTestFonts)
        cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'use-test-fonts', 'true']);
      if (debuggingOptions.verboseSystemLogs) {
        cmd.addAll(&amp;lt;String&amp;gt;['--ez', 'verbose-logging', 'true']);
      }
    }
    cmd.add(apk.launchActivity);
    final String result = (await runCheckedAsync(cmd)).stdout;
    ...

    if (!debuggingOptions.debuggingEnabled)
      return LaunchResult.succeeded();
    try {
      Uri observatoryUri;
      //debug或者profile模式，开启observatory服务来跟设备交互
      if (debuggingOptions.buildInfo.isDebug || debuggingOptions.buildInfo.isProfile) {
        observatoryUri = await observatoryDiscovery.uri;
      }
      return LaunchResult.succeeded(observatoryUri: observatoryUri);
    } catch (error) {
      ...
    } finally {
      await observatoryDiscovery.cancel();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;关于TargetPlatform，是通过adb shell getprop获取属性值来查看ro.product.cpu.abi的值，来获取平台信息arm64/arm/x64/x86。&lt;/p&gt;

&lt;p&gt;该方法的主要功能是以下完成如下几件事：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;通过gradle来构建APK&lt;/li&gt;
  &lt;li&gt;通过adb am force-stop来强杀旧的应用&lt;/li&gt;
  &lt;li&gt;通过adb install来安装APK&lt;/li&gt;
  &lt;li&gt;通过adb am start来启动应用&lt;/li&gt;
  &lt;li&gt;对于debug或者profile模式，等待开启observatory服务&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;25-iosdevicestartapp&quot;&gt;2.5 IOSDevice.startApp&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/ios/devices.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class IOSDevice extends Device {

  Future&amp;lt;LaunchResult&amp;gt; startApp(
    ApplicationPackage package, {
    String mainPath,
    String route,
    DebuggingOptions debuggingOptions,
    Map&amp;lt;String, dynamic&amp;gt; platformArgs,
    bool prebuiltApplication = false,
    bool usesTerminalUi = true,
    bool ipv6 = false,
  }) async {
    if (!prebuiltApplication) {
      //ideviceinfo中获取CPUArchitecture，从而判断是armv7还是arm64
      final String cpuArchitecture = await iMobileDevice.getInfoForDevice(id, 'CPUArchitecture');
      final IOSArch iosArch = getIOSArchForName(cpuArchitecture);

      // Step 1: 构建预编译/DBC应用
      final XcodeBuildResult buildResult = await buildXcodeProject(
          app: package,
          buildInfo: debuggingOptions.buildInfo,
          targetOverride: mainPath,
          buildForDevice: true,
          usesTerminalUi: usesTerminalUi,
          activeArch: iosArch,
      );

    } else {
      if (!await installApp(package))
        return LaunchResult.failed();
    }

    // Step 2: 检查应用程序是否存在于指定路径
    final IOSApp iosApp = package;
    final Directory bundle = fs.directory(iosApp.deviceBundlePath);

    // Step 3: 在设备上尝试安装应用
    final List&amp;lt;String&amp;gt; launchArguments = &amp;lt;String&amp;gt;['--enable-dart-profiling'];

    if (debuggingOptions.startPaused)
      launchArguments.add('--start-paused');

    if (debuggingOptions.disableServiceAuthCodes)
      launchArguments.add('--disable-service-auth-codes');

    if (debuggingOptions.useTestFonts)
      launchArguments.add('--use-test-fonts');

    if (debuggingOptions.debuggingEnabled) {
      launchArguments.add('--enable-checked-mode');
      launchArguments.add('--verify-entry-points');
    }

    if (debuggingOptions.enableSoftwareRendering)
      launchArguments.add('--enable-software-rendering');

    if (debuggingOptions.skiaDeterministicRendering)
      launchArguments.add('--skia-deterministic-rendering');

    if (debuggingOptions.traceSkia)
      launchArguments.add('--trace-skia');

    if (debuggingOptions.dumpSkpOnShaderCompilation)
      launchArguments.add('--dump-skp-on-shader-compilation');

    if (debuggingOptions.verboseSystemLogs) {
      launchArguments.add('--verbose-logging');
    }

    if (platformArgs['trace-startup'] ?? false)
      launchArguments.add('--trace-startup');

    int installationResult = -1;
    Uri localObservatoryUri;

    if (!debuggingOptions.debuggingEnabled) {
      ...
    } else {
      //调试模式，则打开observatory服务
      final ProtocolDiscovery observatoryDiscovery = ProtocolDiscovery.observatory(
        getLogReader(app: package),
        portForwarder: portForwarder,
        hostPort: debuggingOptions.observatoryPort,
        ipv6: ipv6,
      );

      final Future&amp;lt;Uri&amp;gt; forwardObservatoryUri = observatoryDiscovery.uri;
      //启动应用
      final Future&amp;lt;int&amp;gt; launch = const IOSDeploy().runApp(
        deviceId: id,
        bundlePath: bundle.path,
        launchArguments: launchArguments,
      );

      localObservatoryUri = await launch.then&amp;lt;Uri&amp;gt;((int result) async {
        installationResult = result;
        //等待observatory服务启动完成
        return await forwardObservatoryUri;
      }).whenComplete(() {
        observatoryDiscovery.cancel();
      });
    }
    ...
    return LaunchResult.succeeded(observatoryUri: localObservatoryUri);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;构建预编译/DBC应用&lt;/li&gt;
  &lt;li&gt;检查应用程序是否存在于指定路径&lt;/li&gt;
  &lt;li&gt;通过ios-deploy命令来安装并运行应用&lt;/li&gt;
  &lt;li&gt;对于debug或者profile模式，等待开启observatory服务&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;关于运行时参数跟Android基本一致。&lt;/p&gt;

&lt;h3 id=&quot;26-flutter-run参数小结&quot;&gt;2.6 flutter run参数小结&lt;/h3&gt;
&lt;p&gt;flutter run最核心的功能是：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;通过gradle来构建APK&lt;/li&gt;
  &lt;li&gt;通过adb install来安装APK&lt;/li&gt;
  &lt;li&gt;通过adb am start来启动应用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;对于am start过程有很多debuggingOptions可选的调试参数，如下所示：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;flags&lt;/th&gt;
      &lt;th&gt;含义&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;trace-startup&lt;/td&gt;
      &lt;td&gt;跟踪启动&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;route&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable-software-rendering&lt;/td&gt;
      &lt;td&gt;开启软件渲染&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;skia-deterministic-rendering&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace-skia&lt;/td&gt;
      &lt;td&gt;跟踪skia&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace-systrace&lt;/td&gt;
      &lt;td&gt;跟进systrace&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dump-skp-on-shader-compilation&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;enable-checked-mode&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verify-entry-points&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;start-paused&lt;/td&gt;
      &lt;td&gt;应用启动后暂停&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;disable-service-auth-codes&lt;/td&gt;
      &lt;td&gt;关闭observatory服务鉴权&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;use-test-fonts&lt;/td&gt;
      &lt;td&gt;使用测试字体&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;verbose-logging&lt;/td&gt;
      &lt;td&gt;输出verbose日志&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;由此可见，如果你希望运行某个已经安装过的flutter应用，可以跳过安装等环节，可以直接执行应用启动，如下命令：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;adb shell am start -a android.intent.action.RUN -f 0x20000000
    --ez enable-background-compilation true
    --ez enable-dart-profiling true
    --ez disable-service-auth-codes true
    com.gityuan.flutterdemo/.MainActivity
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;三flutter-build-apk命令&quot;&gt;三、flutter build apk命令&lt;/h2&gt;

&lt;p&gt;对于flutter build apk命令，那么对应执行的便是BuildApkCommand类，那么接下来便是执行BuildApkCommand.runCommand()。&lt;/p&gt;

&lt;h3 id=&quot;31-buildapkcommandruncommand&quot;&gt;3.1 BuildApkCommand.runCommand&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/commands/build_apk.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class BuildApkCommand extends BuildSubCommand {
  Future&amp;lt;FlutterCommandResult&amp;gt; runCommand() async {
    // [见小节3.2]
    await buildApk(
      project: await FlutterProject.current(),
      target: targetFile,
      buildInfo: getBuildInfo(),
    );
    return null;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;32-buildapk&quot;&gt;3.2 buildApk&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/apk.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;void&amp;gt; buildApk({
  @required FlutterProject project,
  @required String target,
  BuildInfo buildInfo = BuildInfo.debug,
}) async {
  // [见小节3.3]
  await buildGradleProject(
    project: project,
    buildInfo: buildInfo,
    target: target,
    isBuildingBundle: false,
  );
  androidSdk.reinitialize();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;33-buildgradleproject&quot;&gt;3.3 buildGradleProject&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/gradle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;void&amp;gt; buildGradleProject({
  @required FlutterProject project,
  @required BuildInfo buildInfo,
  @required String target,
  @required bool isBuildingBundle,
}) async {

  updateLocalProperties(project: project, buildInfo: buildInfo);
  // [见小节3.3.1] 获取gradle命令
  final String gradle = await _ensureGradle(project);

  switch (getFlutterPluginVersion(project.android)) {
    case FlutterPluginVersion.none:
    case FlutterPluginVersion.v1:
      return _buildGradleProjectV1(project, gradle);
    case FlutterPluginVersion.managed:
    case FlutterPluginVersion.v2:
      // [见小节3.4]
      return _buildGradleProjectV2(project, gradle, buildInfo, target, isBuildingBundle);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;更新local.properties文件的构建模式、版本名和版本号。 FlutterPlugin v1读取local.properties以确定构建模式， 插件v2使用标准的Android方法来确定要构建的内容。版本名称和版本号由pubspec.yaml文件提供并可以用flutter build命令覆盖。默认的Gradle脚本读取版本名称和编号从local.properties文件中。&lt;/p&gt;

&lt;h4 id=&quot;331-_ensuregradle&quot;&gt;3.3.1 _ensureGradle&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/gradle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;String&amp;gt; _ensureGradle(FlutterProject project) async {
  _cachedGradleExecutable ??= await _initializeGradle(project);
  return _cachedGradleExecutable;
}

Future&amp;lt;String&amp;gt; _initializeGradle(FlutterProject project) async {
  final Directory android = project.android.hostAppGradleRoot;
  final Status status = logger.startProgress('Initializing gradle...', timeout: timeoutConfiguration.slowOperation);
  // [见小节3.3.2]
  String gradle = _locateGradlewExecutable(android);
  if (gradle == null) {
    injectGradleWrapper(android);
    gradle = _locateGradlewExecutable(android);
  }
  // 通过检查版本来验证Gradle可执行文件。如果需要，请下载并安装Gradle发行版。
  await runCheckedAsync(&amp;lt;String&amp;gt;[gradle, '-v'], environment: _gradleEnv);
  status.stop();
  return gradle;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;332-_locategradlewexecutable&quot;&gt;3.3.2 _locateGradlewExecutable&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/gradle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;String _locateGradlewExecutable(Directory directory) {
  final File gradle = directory.childFile(
    platform.isWindows ? 'gradlew.bat' : 'gradlew',
  );

  if (gradle.existsSync()) {
    os.makeExecutable(gradle);
    return gradle.absolute.path;
  } else {
    return null;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;对于window环境，则是gradlew.bat；&lt;/li&gt;
  &lt;li&gt;其他环境，则是gradlew；&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;34-_buildgradleprojectv2&quot;&gt;3.4 _buildGradleProjectV2&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/gradle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;void&amp;gt; _buildGradleProjectV2(
  FlutterProject flutterProject,
  String gradle,
  BuildInfo buildInfo,
  String target,
  bool isBuildingBundle,  
) async {
  final GradleProject project = await _gradleProject();

  String assembleTask;
  // 前面传递过来isBuildingBundle为false
  if (isBuildingBundle) {
    assembleTask = project.bundleTaskFor(buildInfo);
  } else {
    assembleTask = project.assembleTaskFor(buildInfo);
  }
  //获取gradle路径
  final String gradlePath = fs.file(gradle).absolute.path;
  final List&amp;lt;String&amp;gt; command = &amp;lt;String&amp;gt;[gradlePath];

  if (artifacts is LocalEngineArtifacts) {
    final LocalEngineArtifacts localEngineArtifacts = artifacts;
    command.add('-PlocalEngineOut=${localEngineArtifacts.engineOutPath}');
  }
  if (target != null) {
    command.add('-Ptarget=$target');
  }
  command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
  if (buildInfo.compilationTraceFilePath != null)
    command.add('-Pcompilation-trace-file=${buildInfo.compilationTraceFilePath}');
  if (buildInfo.createPatch)
    command.add('-Ppatch=true');
  if (buildInfo.extraFrontEndOptions != null)
    command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}');
  if (buildInfo.extraGenSnapshotOptions != null)
    command.add('-Pextra-gen-snapshot-options=${buildInfo.extraGenSnapshotOptions}');
  if (buildInfo.fileSystemRoots != null &amp;amp;&amp;amp; buildInfo.fileSystemRoots.isNotEmpty)
    command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}');
  if (buildInfo.fileSystemScheme != null)
    command.add('-Pfilesystem-scheme=${buildInfo.fileSystemScheme}');
  if (buildInfo.buildSharedLibrary &amp;amp;&amp;amp; androidSdk.ndk != null) {
    command.add('-Pbuild-shared-library=true');
  }
  if (buildInfo.targetPlatform != null)
    command.add('-Ptarget-platform=${getNameForTargetPlatform(buildInfo.targetPlatform)}');
  command.add(assembleTask);

  bool potentialAndroidXFailure = false;
  //运行组装了一串参数的gradle命令
  final int exitCode = await runCommandAndStreamOutput(
    command,
    workingDirectory: flutterProject.android.hostAppGradleRoot.path,
    allowReentrantFlutter: true,
    environment: _gradleEnv,
    ...
  );
  status.stop();

  if (!isBuildingBundle) {
    //获取apk文件
    final File apkFile = _findApkFile(project, buildInfo);
    //将APK复制到app.apk，以便`flutter run`, `flutter install`这些命令能找到
    apkFile.copySync(project.apkDirectory.childFile('app.apk').path);

    final File apkShaFile = project.apkDirectory.childFile('app.apk.sha1');
    apkShaFile.writeAsStringSync(calculateSha(apkFile));
    ...
  } else {
    ...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;构建过程主要是调用gradle命令，如下所示&lt;/p&gt;

&lt;h4 id=&quot;341-gradle命令与参数说明&quot;&gt;3.4.1 gradle命令与参数说明&lt;/h4&gt;

&lt;p&gt;gradlew命令：&lt;/p&gt;

&lt;p&gt;gradlew -Ptarget=lib/main.dart -Ptrack-widget-creation=false -Ptarget-platform=android-arm assembleRelease&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;参数&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;PlocalEngineOut&lt;/td&gt;
      &lt;td&gt;引擎产物&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ptarget&lt;/td&gt;
      &lt;td&gt;取值lib/main.dart&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ptrack-widget-creation&lt;/td&gt;
      &lt;td&gt;默认为false&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pcompilation-trace-file&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ppatch&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pextra-front-end-options&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pextra-gen-snapshot-options&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pfilesystem-roots&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pfilesystem-scheme&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Pbuild-shared-library&lt;/td&gt;
      &lt;td&gt;是否采取共享库&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ptarget-platform&lt;/td&gt;
      &lt;td&gt;目标平台&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;35-flutter的gradle构建&quot;&gt;3.5 flutter的gradle构建&lt;/h3&gt;

&lt;p&gt;gradlew assembleRelease这便是Anroid平台比较常见的编译命令。 会执行build.gradle文件，里面有一行重要的语句，如下所示。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apply from: &quot;$flutterRoot/packages/flutter_tools/gradle/flutter.gradle&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;351-fluttergradle&quot;&gt;3.5.1 flutter.gradle&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; gradle/flutter.gradle]&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CopySpec getAssets() {
    return project.copySpec {
        from &quot;${intermediateDir}&quot;

        include &quot;flutter_assets/**&quot; // the working dir and its files

        if (buildMode == 'release' || buildMode == 'profile') {
            if (buildSharedLibrary) {
                include &quot;app.so&quot;
            } else {
                include &quot;vm_snapshot_data&quot;
                include &quot;vm_snapshot_instr&quot;
                include &quot;isolate_snapshot_data&quot;
                include &quot;isolate_snapshot_instr&quot;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可知flutter产物可以是app.so或者是xxx_snapshot_xxx。&lt;/p&gt;

&lt;h4 id=&quot;352-buildbundle&quot;&gt;3.5.2 buildBundle&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; gradle/flutter.gradle]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void buildBundle() {
    intermediateDir.mkdirs()

    if (buildMode == &quot;profile&quot; || buildMode == &quot;release&quot;) {
        //执行flutter build aot
        project.exec {
            executable flutterExecutable.absolutePath
            workingDir sourceDir
            if (localEngine != null) {
                args &quot;--local-engine&quot;, localEngine
                args &quot;--local-engine-src-path&quot;, localEngineSrcPath
            }
            args &quot;build&quot;, &quot;aot&quot;
            args &quot;--suppress-analytics&quot;
            args &quot;--quiet&quot;
            args &quot;--target&quot;, targetPath
            args &quot;--target-platform&quot;, &quot;android-arm&quot;
            args &quot;--output-dir&quot;, &quot;${intermediateDir}&quot;
            if (trackWidgetCreation) {
                args &quot;--track-widget-creation&quot;
            }
            if (extraFrontEndOptions != null) {
                args &quot;--extra-front-end-options&quot;, &quot;${extraFrontEndOptions}&quot;
            }
            if (extraGenSnapshotOptions != null) {
                args &quot;--extra-gen-snapshot-options&quot;, &quot;${extraGenSnapshotOptions}&quot;
            }
            if (buildSharedLibrary) {
                args &quot;--build-shared-library&quot;
            }
            if (targetPlatform != null) {
                args &quot;--target-platform&quot;, &quot;${targetPlatform}&quot;
            }
            args &quot;--${buildMode}&quot;
        }
    }
    //flutter build bundle
    project.exec {
        executable flutterExecutable.absolutePath
        workingDir sourceDir
        if (localEngine != null) {
            args &quot;--local-engine&quot;, localEngine
            args &quot;--local-engine-src-path&quot;, localEngineSrcPath
        }
        args &quot;build&quot;, &quot;bundle&quot;
        args &quot;--suppress-analytics&quot;
        args &quot;--target&quot;, targetPath
        if (verbose) {
            args &quot;--verbose&quot;
        }
        if (fileSystemRoots != null) {
            for (root in fileSystemRoots) {
                args &quot;--filesystem-root&quot;, root
            }
        }
        if (fileSystemScheme != null) {
            args &quot;--filesystem-scheme&quot;, fileSystemScheme
        }
        if (trackWidgetCreation) {
            args &quot;--track-widget-creation&quot;
        }
        if (compilationTraceFilePath != null) {
            args &quot;--compilation-trace-file&quot;, compilationTraceFilePath
        }
        if (createPatch) {
            args &quot;--patch&quot;
            args &quot;--build-number&quot;, project.android.defaultConfig.versionCode
            if (buildNumber != null) {
                assert buildNumber == project.android.defaultConfig.versionCode
            }
        }
        if (baselineDir != null) {
            args &quot;--baseline-dir&quot;, baselineDir
        }
        if (extraFrontEndOptions != null) {
            args &quot;--extra-front-end-options&quot;, &quot;${extraFrontEndOptions}&quot;
        }
        if (extraGenSnapshotOptions != null) {
            args &quot;--extra-gen-snapshot-options&quot;, &quot;${extraGenSnapshotOptions}&quot;
        }
        if (targetPlatform != null) {
            args &quot;--target-platform&quot;, &quot;${targetPlatform}&quot;
        }
        if (buildMode == &quot;release&quot; || buildMode == &quot;profile&quot;) {
            args &quot;--precompiled&quot;
        } else {
            args &quot;--depfile&quot;, &quot;${intermediateDir}/snapshot_blob.bin.d&quot;
        }
        args &quot;--asset-dir&quot;, &quot;${intermediateDir}/flutter_assets&quot;
        if (buildMode == &quot;debug&quot;) {
            args &quot;--debug&quot;
        }
        if (buildMode == &quot;profile&quot; || buildMode == &quot;dynamicProfile&quot;) {
            args &quot;--profile&quot;
        }
        if (buildMode == &quot;release&quot; || buildMode == &quot;dynamicRelease&quot;) {
            args &quot;--release&quot;
        }
        if (buildMode == &quot;dynamicProfile&quot; || buildMode == &quot;dynamicRelease&quot;) {
            args &quot;--dynamic&quot;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法核心功能是两部分：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;flutter build aot：针对profile或者release模式&lt;/li&gt;
  &lt;li&gt;flutter build bundle&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;36-build-apk等价命令&quot;&gt;3.6 build apk等价命令&lt;/h3&gt;

&lt;p&gt;build apk的过程主要分为以下两个过程，也就是[小节3.4.2]的buildBundle中过程展开后的如下两个命令：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;flutter build aot
  --suppress-analytics
  --quiet
  --target lib/main.dart
  --output-dir /build/app/intermediates/flutter/release/
  --target-platform android-arm
  --extra-front-end-options
  --extra-gen-snapshot-options
  --release
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;flutter build bundle
  --suppress-analytics
  --verbose  
  --target lib/main.dart
  --target-platform android-arm
  --extra-front-end-options
  --extra-gen-snapshot-options
  --asset-dir /build/app/intermediates/flutter/release/flutter_assets
  --precompiled
  --release
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;四-flutter-build-aot命令&quot;&gt;四、 flutter build aot命令&lt;/h2&gt;

&lt;h3 id=&quot;41-buildaotcommandruncommand&quot;&gt;4.1 BuildAotCommand.runCommand&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/commands/build_aot.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmentArtifacts {

  Future&amp;lt;FlutterCommandResult&amp;gt; runCommand() async {
    //解析目标平台
    final String targetPlatform = argResults['target-platform'];
    final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
    //解析编译模式
    final BuildMode buildMode = getBuildMode();

    Status status;
    //解析aot产物路径
    final String outputPath = argResults['output-dir'] ?? getAotBuildDirectory();
    final bool reportTimings = argResults['report-timings'];
    try {
      //解析dart主函数路径
      String mainPath = findMainDartFile(targetFile);
      final AOTSnapshotter snapshotter = AOTSnapshotter(reportTimings: reportTimings);

      //编译到内核 [见小节4.2]
      mainPath = await snapshotter.compileKernel(
        platform: platform,
        buildMode: buildMode,
        mainPath: mainPath,
        packagesPath: PackageMap.globalPackagesPath,
        trackWidgetCreation: false,
        outputPath: outputPath,
        extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
      );

      //构建AOT快照
      if (platform == TargetPlatform.ios) {
        // iOS架构分为armv7和arm64
        final Iterable&amp;lt;IOSArch&amp;gt; buildArchs = argResults['ios-arch'].map&amp;lt;IOSArch&amp;gt;(getIOSArchForName);
        final Map&amp;lt;IOSArch, String&amp;gt; iosBuilds = &amp;lt;IOSArch, String&amp;gt;{};
        for (IOSArch arch in buildArchs)
          iosBuilds[arch] = fs.path.join(outputPath, getNameForIOSArch(arch));

        final Map&amp;lt;IOSArch, Future&amp;lt;int&amp;gt;&amp;gt; exitCodes = &amp;lt;IOSArch, Future&amp;lt;int&amp;gt;&amp;gt;{};
        iosBuilds.forEach((IOSArch iosArch, String outputPath) {
          //生成AOT快照 并编译为特定架构的App.framework [见小节4.4]
          exitCodes[iosArch] = snapshotter.build(
            platform: platform,
            iosArch: iosArch,
            buildMode: buildMode,
            mainPath: mainPath,
            packagesPath: PackageMap.globalPackagesPath,
            outputPath: outputPath,
            buildSharedLibrary: false,
            extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
          ).then&amp;lt;int&amp;gt;((int buildExitCode) {
            return buildExitCode;
          });
        });

        //将特定于架构的App.frameworks合并到一个多架构的App.framework中
        if ((await Future.wait&amp;lt;int&amp;gt;(exitCodes.values)).every((int buildExitCode) =&amp;gt; buildExitCode == 0)) {
          final Iterable&amp;lt;String&amp;gt; dylibs = iosBuilds.values.map&amp;lt;String&amp;gt;((String outputDir) =&amp;gt; fs.path.join(outputDir, 'App.framework', 'App'));
          fs.directory(fs.path.join(outputPath, 'App.framework'))..createSync();
          await runCheckedAsync(&amp;lt;String&amp;gt;['lipo']
            ..addAll(dylibs)
            ..addAll(&amp;lt;String&amp;gt;['-create', '-output', fs.path.join(outputPath, 'App.framework', 'App')]),
          );
        } else {
          status?.cancel();
          exitCodes.forEach((IOSArch iosArch, Future&amp;lt;int&amp;gt; exitCodeFuture) async {
            final int buildExitCode = await exitCodeFuture;
            printError('Snapshotting ($iosArch) exited with non-zero exit code: $buildExitCode');
          });
        }
      } else {
        // Android AOT快照 [见小节4.4]
        final int snapshotExitCode = await snapshotter.build(
          platform: platform,
          buildMode: buildMode,
          mainPath: mainPath,
          packagesPath: PackageMap.globalPackagesPath,
          outputPath: outputPath,
          buildSharedLibrary: argResults['build-shared-library'],
          extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
        );
      }
    } on String catch (error) {
      ...
    }
    ...
    return null;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;build aot的参数解读，见小节[1.2.3];&lt;/li&gt;
  &lt;li&gt;生成kernel文件， 这是dart定义的一种特殊数据格式，由dart虚拟机解释模式执行；&lt;/li&gt;
  &lt;li&gt;生成AOT可执行文件，根据kernel来生成的一种二进制机器码，执行速度更快；release模式打进apk的便是机器码；&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;42-compilekernel&quot;&gt;4.2 compileKernel&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/base/build.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class AOTSnapshotter {

  Future&amp;lt;String&amp;gt; compileKernel({
    @required TargetPlatform platform,
    @required BuildMode buildMode,
    @required String mainPath,
    @required String packagesPath,
    @required String outputPath,
    @required bool trackWidgetCreation,
    List&amp;lt;String&amp;gt; extraFrontEndOptions = const &amp;lt;String&amp;gt;[],
  }) async {
    final FlutterProject flutterProject = await FlutterProject.current();
    final Directory outputDir = fs.directory(outputPath);
    outputDir.createSync(recursive: true);
    //路径为 build/aot/kernel_compile.d
    final String depfilePath = fs.path.join(outputPath, 'kernel_compile.d');
    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
    final CompilerOutput compilerOutput = await _timedStep('frontend',
      //[见小节4.3]
      () =&amp;gt; kernelCompiler.compile(
      sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath, mode: buildMode),
      mainPath: mainPath,
      packagesPath: packagesPath,
      outputFilePath: getKernelPathForTransformerOptions(
        fs.path.join(outputPath, 'app.dill'),
        trackWidgetCreation: trackWidgetCreation,
      ),
      depFilePath: depfilePath,
      extraFrontEndOptions: extraFrontEndOptions,
      linkPlatformKernelIn: true,
      aot: true,
      trackWidgetCreation: trackWidgetCreation,
      targetProductVm: buildMode == BuildMode.release,
    ));

    //将路径写入frontend_server，因为当更改时需要重新生成
    final String frontendPath = artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
    await fs.directory(outputPath).childFile('frontend_server.d').writeAsString('frontend_server.d: $frontendPath\n');
    return compilerOutput?.outputFilename;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;43-kernelcompilercompile&quot;&gt;4.3 KernelCompiler.compile&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/compile.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class KernelCompiler {

  Future&amp;lt;CompilerOutput&amp;gt; compile({
    String sdkRoot,
    String mainPath,
    String outputFilePath,
    String depFilePath,
    TargetModel targetModel = TargetModel.flutter,
    bool linkPlatformKernelIn = false,
    bool aot = false,
    @required bool trackWidgetCreation,
    List&amp;lt;String&amp;gt; extraFrontEndOptions,
    String incrementalCompilerByteStorePath,
    String packagesPath,
    List&amp;lt;String&amp;gt; fileSystemRoots,
    String fileSystemScheme,
    bool targetProductVm = false,
    String initializeFromDill,
  }) async {
    final String frontendServer = artifacts.getArtifactPath(
      Artifact.frontendServerSnapshotForEngineDartSdk
    );
    FlutterProject flutterProject;
    if (fs.file('pubspec.yaml').existsSync()) {
      flutterProject = await FlutterProject.current();
    }

    Fingerprinter fingerprinter;
    if (depFilePath != null) {
      fingerprinter = Fingerprinter(
        fingerprintPath: '$depFilePath.fingerprint',
        paths: &amp;lt;String&amp;gt;[mainPath],
        properties: &amp;lt;String, String&amp;gt;{
          'entryPoint': mainPath,
          'trackWidgetCreation': trackWidgetCreation.toString(),
          'linkPlatformKernelIn': linkPlatformKernelIn.toString(),
          'engineHash': Cache.instance.engineRevision,
          'buildersUsed': '${flutterProject != null ? flutterProject.hasBuilders : false}',
        },
        depfilePaths: &amp;lt;String&amp;gt;[depFilePath],
        pathFilter: (String path) =&amp;gt; !path.startsWith('/b/build/slave/'),
      );

    }
    //获取dart命令路径
    final String engineDartPath = artifacts.getArtifactPath(Artifact.engineDartBinary);

    }
    final List&amp;lt;String&amp;gt; command = &amp;lt;String&amp;gt;[
      engineDartPath,
      frontendServer,
      '--sdk-root',
      sdkRoot,
      '--strong',
      '--target=$targetModel',
    ];
    if (trackWidgetCreation)
      command.add('--track-widget-creation');
    if (!linkPlatformKernelIn)
      command.add('--no-link-platform');
    if (aot) {
      command.add('--aot');
      command.add('--tfa');
    }
    if (targetProductVm) {
      command.add('-Ddart.vm.product=true');
    }
    if (incrementalCompilerByteStorePath != null) {
      command.add('--incremental');
    }
    Uri mainUri;
    if (packagesPath != null) {
      command.addAll(&amp;lt;String&amp;gt;['--packages', packagesPath]);
      mainUri = PackageUriMapper.findUri(mainPath, packagesPath, fileSystemScheme, fileSystemRoots);
    }
    if (outputFilePath != null) {
      command.addAll(&amp;lt;String&amp;gt;['--output-dill', outputFilePath]);
    }
    if (depFilePath != null &amp;amp;&amp;amp; (fileSystemRoots == null || fileSystemRoots.isEmpty)) {
      command.addAll(&amp;lt;String&amp;gt;['--depfile', depFilePath]);
    }
    if (fileSystemRoots != null) {
      for (String root in fileSystemRoots) {
        command.addAll(&amp;lt;String&amp;gt;['--filesystem-root', root]);
      }
    }
    if (fileSystemScheme != null) {
      command.addAll(&amp;lt;String&amp;gt;['--filesystem-scheme', fileSystemScheme]);
    }
    if (initializeFromDill != null) {
      command.addAll(&amp;lt;String&amp;gt;['--initialize-from-dill', initializeFromDill]);
    }

    if (extraFrontEndOptions != null)
      command.addAll(extraFrontEndOptions);

    command.add(mainUri?.toString() ?? mainPath);
    ...
    //执行命令 [见小节4.3.1]
    await processManager.start(command);
    await fingerprinter.writeFingerprint();
    ...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;431-frontend_server命令&quot;&gt;4.3.1 frontend_server命令&lt;/h4&gt;
&lt;p&gt;KernelCompiler.compile()过程等价于如下命令：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;flutter/bin/cache/dart-sdk/bin/dart
  flutter/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot
  --sdk-root flutter/bin/cache/artifacts/engine/common/flutter_patched_sdk_product/
  --strong
  --target=flutter
  --aot --tfa
  -Ddart.vm.product=true
  --packages .packages
  --output-dill build/app/intermediates/flutter/release/app.dill
  --depfile     build/app/intermediates/flutter/release/kernel_compile.d
  package:flutter_app/main.dart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;可见，通过dart虚拟机启动frontend_server.dart.snapshot，将dart代码编程成app.dill形式的kernel文件。frontend_server.dart.snapshot的入口位于Flutter引擎中的
flutter/frontend_server/bin/starter.dart。&lt;/p&gt;

&lt;p&gt;关于这个过程的kernel编译以及文件的生成过程，将在下一篇文章将进一步展开说明。&lt;/p&gt;

&lt;p&gt;再回到[小节4.1]，接下来执行AOTSnapshotter.build()方法。&lt;/p&gt;

&lt;h3 id=&quot;44-aotsnapshotterbuild&quot;&gt;4.4 AOTSnapshotter.build&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/base/build.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class AOTSnapshotter {

  Future&amp;lt;int&amp;gt; build({
    @required TargetPlatform platform,
    @required BuildMode buildMode,
    @required String mainPath,
    @required String packagesPath,
    @required String outputPath,
    @required bool buildSharedLibrary,
    IOSArch iosArch,
    List&amp;lt;String&amp;gt; extraGenSnapshotOptions = const &amp;lt;String&amp;gt;[],
  }) async {
    FlutterProject flutterProject;
    if (fs.file('pubspec.yaml').existsSync()) {
      flutterProject = await FlutterProject.current();
    }
    //非debug模式下的android arm/arm64或者ios才支持aot
    if (!_isValidAotPlatform(platform, buildMode)) {
      return 1;
    }

    //iOS忽略共享库
    if (platform == TargetPlatform.ios)
      buildSharedLibrary = false;

    final PackageMap packageMap = PackageMap(packagesPath);

    final Directory outputDir = fs.directory(outputPath);
    outputDir.createSync(recursive: true);

    final String skyEnginePkg = _getPackagePath(packageMap, 'sky_engine');
    final String uiPath = fs.path.join(skyEnginePkg, 'lib', 'ui', 'ui.dart');
    final String vmServicePath = fs.path.join(skyEnginePkg, 'sdk_ext', 'vmservice_io.dart');

    final List&amp;lt;String&amp;gt; inputPaths = &amp;lt;String&amp;gt;[uiPath, vmServicePath, mainPath];
    final Set&amp;lt;String&amp;gt; outputPaths = &amp;lt;String&amp;gt;{};

    final String depfilePath = fs.path.join(outputDir.path, 'snapshot.d');
    final List&amp;lt;String&amp;gt; genSnapshotArgs = &amp;lt;String&amp;gt;['--deterministic',];
    if (extraGenSnapshotOptions != null &amp;amp;&amp;amp; extraGenSnapshotOptions.isNotEmpty) {
      genSnapshotArgs.addAll(extraGenSnapshotOptions);
    }

    final String assembly = fs.path.join(outputDir.path, 'snapshot_assembly.S');
    if (buildSharedLibrary || platform == TargetPlatform.ios) {
      // Assembly AOT snapshot.
      outputPaths.add(assembly);
      genSnapshotArgs.add('--snapshot_kind=app-aot-assembly');
      genSnapshotArgs.add('--assembly=$assembly');
    } else {
      // Blob AOT snapshot.
      final String vmSnapshotData = fs.path.join(outputDir.path, 'vm_snapshot_data');
      final String isolateSnapshotData = fs.path.join(outputDir.path, 'isolate_snapshot_data');
      final String vmSnapshotInstructions = fs.path.join(outputDir.path, 'vm_snapshot_instr');
      final String isolateSnapshotInstructions = fs.path.join(outputDir.path, 'isolate_snapshot_instr');
      outputPaths.addAll(&amp;lt;String&amp;gt;[vmSnapshotData, isolateSnapshotData, vmSnapshotInstructions, isolateSnapshotInstructions]);
      genSnapshotArgs.addAll(&amp;lt;String&amp;gt;[
        '--snapshot_kind=app-aot-blobs',
        '--vm_snapshot_data=$vmSnapshotData',
        '--isolate_snapshot_data=$isolateSnapshotData',
        '--vm_snapshot_instructions=$vmSnapshotInstructions',
        '--isolate_snapshot_instructions=$isolateSnapshotInstructions',
      ]);
    }

    if (platform == TargetPlatform.android_arm || iosArch == IOSArch.armv7) {
      //将softfp用于Android armv7设备。这是armv7 iOS构建的默认设置
      genSnapshotArgs.add('--no-sim-use-hardfp');
      // Pixel不支持32位模式
      genSnapshotArgs.add('--no-use-integer-division');
    }
    genSnapshotArgs.add(mainPath);

    final Fingerprinter fingerprinter = Fingerprinter(
      fingerprintPath: '$depfilePath.fingerprint',
      paths: &amp;lt;String&amp;gt;[mainPath]..addAll(inputPaths)..addAll(outputPaths),
      properties: &amp;lt;String, String&amp;gt;{
        'buildMode': buildMode.toString(),
        'targetPlatform': platform.toString(),
        'entryPoint': mainPath,
        'sharedLib': buildSharedLibrary.toString(),
        'extraGenSnapshotOptions': extraGenSnapshotOptions.join(' '),
        'engineHash': Cache.instance.engineRevision,
        'buildersUsed': '${flutterProject != null ? flutterProject.hasBuilders : false}',
      },
      depfilePaths: &amp;lt;String&amp;gt;[],
    );
    //自从上次运行以来，输入和输出都没有更改，则跳过该构建流程
    if (await fingerprinter.doesFingerprintMatch()) {
      return 0;
    }

    final SnapshotType snapshotType = SnapshotType(platform, buildMode);
    //[见小节4.5]
    final int genSnapshotExitCode = await _timedStep('gen_snapshot',
      () =&amp;gt; genSnapshot.run(
        snapshotType: snapshotType,
        additionalArgs: genSnapshotArgs,
        iosArch: iosArch,
    ));

    // 将路径写入gen_snapshot，因为在滚动Dart SDK时必须重新生成快照
    final String genSnapshotPath = GenSnapshot.getSnapshotterPath(snapshotType);
    await outputDir.childFile('gen_snapshot.d').writeAsString('gen_snapshot.d: $genSnapshotPath\n');

    //在iOS上，使用Xcode将snapshot编译到动态库中，最终可见将其链接到应用程序。
    if (platform == TargetPlatform.ios) {
      final RunResult result = await _buildIosFramework(iosArch: iosArch, assemblyPath: assembly, outputPath: outputDir.path);
    } else if (buildSharedLibrary) {
      final RunResult result = await _buildAndroidSharedLibrary(assemblyPath: assembly, outputPath: outputDir.path);
    }

    //计算和记录构建指纹
    await fingerprinter.writeFingerprint();
    return 0;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;对于iOS或者采用共享库方式的Android，则产物类型snapshot_kind为app-aot-assembly
    &lt;ul&gt;
      &lt;li&gt;对于Android，则生成app.so&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;对于非共享库方式的Android，则产物类型snapshot_kind为app-aot-blobs
    &lt;ul&gt;
      &lt;li&gt;生成vmSnapshotData，isolateSnapshotData，vmSnapshotInstructions，isolateSnapshotInstructions这四个产物&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;45-gensnapshotrun&quot;&gt;4.5 GenSnapshot.run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/base/build.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class GenSnapshot {

  Future&amp;lt;int&amp;gt; run({
    @required SnapshotType snapshotType,
    IOSArch iosArch,
    Iterable&amp;lt;String&amp;gt; additionalArgs = const &amp;lt;String&amp;gt;[],
  }) {
    final List&amp;lt;String&amp;gt; args = &amp;lt;String&amp;gt;[
      '--causal_async_stacks',
    ]..addAll(additionalArgs);
    //获取gen_snapshot命令的路径
    final String snapshotterPath = getSnapshotterPath(snapshotType);

    //iOS gen_snapshot是一个多体系结构二进制文件。 作为i386二进制文件运行将生成armv7代码。 作为x86_64二进制文件运行将生成arm64代码。
    // /usr/bin/arch可用于运行具有指定体系结构的二进制文件
    if (snapshotType.platform == TargetPlatform.ios) {
      final String hostArch = iosArch == IOSArch.armv7 ? '-i386' : '-x86_64';
      return runCommandAndStreamOutput(&amp;lt;String&amp;gt;['/usr/bin/arch', hostArch, snapshotterPath]..addAll(args));
    }
    return runCommandAndStreamOutput(&amp;lt;String&amp;gt;[snapshotterPath]..addAll(args));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;runCommandAndStreamOutput便会执行如下这一串命令：&lt;/p&gt;

&lt;h4 id=&quot;451-gensnapshot命令&quot;&gt;4.5.1 GenSnapshot命令&lt;/h4&gt;

&lt;p&gt;GenSnapshot.run具体命令根据前面的封装，最终等价于：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;// 这是针对Android的genSnapshot命令
flutter/bin/cache/artifacts/engine/android-arm-release/darwin-x64/gen_snapshot
  --causal_async_stacks
  --deterministic
  --snapshot_kind=app-aot-blobs
  --vm_snapshot_data=build/app/intermediates/flutter/release/vm_snapshot_data
  --isolate_snapshot_data=build/app/intermediates/flutter/release/isolate_snapshot_data
  --vm_snapshot_instructions=build/app/intermediates/flutter/release/vm_snapshot_instr
  --isolate_snapshot_instructions=build/app/intermediates/flutter/release/isolate_snapshot_instr
  --no-sim-use-hardfp
  --no-use-integer-division
  build/aot/app.dill
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;//这是针对iOS的genSnapshot命令
/usr/bin/arch -x86_64 flutter/bin/cache/artifacts/engine/ios-release/gen_snapshot
  --causal_async_stacks
  --deterministic
  --snapshot_kind=app-aot-assembly
  --assembly=build/aot/arm64/snapshot_assembly.S
  build/aot/app.dill
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处gen_snapshot是一个二进制可执行文件，所对应的执行方法源码为third_party/dart/runtime/bin/gen_snapshot.cc，将在下一篇文章将进一步展开说明。&lt;/p&gt;

&lt;h2 id=&quot;五flutter-build-bundle命令&quot;&gt;五、flutter build bundle命令&lt;/h2&gt;

&lt;h3 id=&quot;51-buildbundlecommandruncommand&quot;&gt;5.1 BuildBundleCommand.runCommand&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/commands/build_bundle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class BuildBundleCommand extends BuildSubCommand {
  Future&amp;lt;FlutterCommandResult&amp;gt; runCommand() async {
    final String targetPlatform = argResults['target-platform'];
    final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
    final BuildMode buildMode = getBuildMode();

    final String buildNumber = argResults['build-number'] != null ? argResults['build-number'] : null;
    //[见小节5.2]
    await build(
      platform: platform,
      buildMode: buildMode,
      mainPath: targetFile,
      manifestPath: argResults['manifest'],
      depfilePath: argResults['depfile'],
      privateKeyPath: argResults['private-key'],
      assetDirPath: argResults['asset-dir'],
      precompiledSnapshot: argResults['precompiled'],
      reportLicensedPackages: argResults['report-licensed-packages'],
      trackWidgetCreation: argResults['track-widget-creation'],
      compilationTraceFilePath: argResults['compilation-trace-file'],
      createPatch: argResults['patch'],
      buildNumber: buildNumber,
      baselineDir: argResults['baseline-dir'],
      extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions],
      extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions],
      fileSystemScheme: argResults['filesystem-scheme'],
      fileSystemRoots: argResults['filesystem-root'],
    );
    return null;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;52-build&quot;&gt;5.2 build&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/bundle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;void&amp;gt; build(...) async {
  ...
  final AssetBundle assets = await buildAssets(
    manifestPath: manifestPath,
    assetDirPath: assetDirPath,
    packagesPath: packagesPath,
    reportLicensedPackages: reportLicensedPackages,
  );

  if (!precompiledSnapshot) {
    ... //relase模式，参数中会带上--precompiled，则不会编译kernel文件
  }

  //[见小节5.3]
  await assemble(
    buildMode: buildMode,
    assetBundle: assets,
    kernelContent: kernelContent,
    privateKeyPath: privateKeyPath,
    assetDirPath: assetDirPath,
    compilationTraceFilePath: compilationTraceFilePath,
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;53-assemble&quot;&gt;5.3 assemble&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/bundle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;void&amp;gt; assemble({
  BuildMode buildMode,
  AssetBundle assetBundle,
  DevFSContent kernelContent,
  String privateKeyPath = defaultPrivateKeyPath,
  String assetDirPath,
  String compilationTraceFilePath,
}) async {
  // 目录 build/flutter_assets/
  assetDirPath ??= getAssetBuildDirectory();

  final Map&amp;lt;String, DevFSContent&amp;gt; assetEntries = Map&amp;lt;String, DevFSContent&amp;gt;.from(assetBundle.entries);
  if (kernelContent != null) {
    if (compilationTraceFilePath != null) {
      final String vmSnapshotData = artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: buildMode);
      final String isolateSnapshotData = fs.path.join(getBuildDirectory(), _kIsolateSnapshotData);
      final String isolateSnapshotInstr = fs.path.join(getBuildDirectory(), _kIsolateSnapshotInstr);
      assetEntries[_kVMSnapshotData] = DevFSFileContent(fs.file(vmSnapshotData));
      assetEntries[_kIsolateSnapshotData] = DevFSFileContent(fs.file(isolateSnapshotData));
      assetEntries[_kIsolateSnapshotInstr] = DevFSFileContent(fs.file(isolateSnapshotInstr));
    } else {
      final String vmSnapshotData = artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: buildMode);
      final String isolateSnapshotData = artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: buildMode);
      assetEntries[_kKernelKey] = kernelContent;
      assetEntries[_kVMSnapshotData] = DevFSFileContent(fs.file(vmSnapshotData));
      assetEntries[_kIsolateSnapshotData] = DevFSFileContent(fs.file(isolateSnapshotData));
    }
  }
  ensureDirectoryExists(assetDirPath);
  //[见小节5.4]
  await writeBundle(fs.directory(assetDirPath), assetEntries);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;54-writebundle&quot;&gt;5.4 writeBundle&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/bundle.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;void&amp;gt; writeBundle(
  Directory bundleDir,
  Map&amp;lt;String, DevFSContent&amp;gt; assetEntries,
) async {
  if (bundleDir.existsSync())
    bundleDir.deleteSync(recursive: true);
  bundleDir.createSync(recursive: true);

  await Future.wait&amp;lt;void&amp;gt;(
    assetEntries.entries.map&amp;lt;Future&amp;lt;void&amp;gt;&amp;gt;((MapEntry&amp;lt;String, DevFSContent&amp;gt; entry) async {
      final File file = fs.file(fs.path.join(bundleDir.path, entry.key));
      file.parent.createSync(recursive: true);
      await file.writeAsBytes(await entry.value.contentsAsBytes());
    }));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将一些文件放进了build/app/intermediates/flutter/release/flutter_assets目录下。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AssetManifest.json&lt;/li&gt;
  &lt;li&gt;FontManifest.json&lt;/li&gt;
  &lt;li&gt;LICENSE&lt;/li&gt;
  &lt;li&gt;fonts/MaterialIcons-Regular.ttf&lt;/li&gt;
  &lt;li&gt;packages/cupertino_icons/assets/CupertinoIcons.ttf&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;六flutter-install命令&quot;&gt;六、flutter install命令&lt;/h2&gt;

&lt;h3 id=&quot;61-installcommandruncommand&quot;&gt;6.1 InstallCommand.runCommand&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/commands/install.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class InstallCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
  Future&amp;lt;FlutterCommandResult&amp;gt; runCommand() async {
    final ApplicationPackage package = await applicationPackages.getPackageForPlatform(await device.targetPlatform);

    Cache.releaseLockEarly();
    //[见小节6.2]
    if (!await installApp(device, package))
      throwToolExit('Install failed');

    return null;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;62-installapp&quot;&gt;6.2 installApp&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/commands/install.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;bool&amp;gt; installApp(Device device, ApplicationPackage package, { bool uninstall = true }) async {
  //当app已存在，则先卸载老的apk，再安装新的apk
  if (uninstall &amp;amp;&amp;amp; await device.isAppInstalled(package)) {
    if (!await device.uninstallApp(package))
      printError('Warning: uninstalling old version failed');
  }

  return device.installApp(package);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;63-androiddeviceinstallapp&quot;&gt;6.3 AndroidDevice.installApp&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/android/android_device.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;bool&amp;gt; installApp(ApplicationPackage app) async {
  final AndroidApk apk = app;
  ...
  //执行的命令是adb install -t -r [apk_path]来安装APK
  final RunResult installResult = await runAsync(adbCommandForDevice(&amp;lt;String&amp;gt;['install', '-t', '-r', apk.file.path]));
  status.stop();
  //执行完安装命令，会再通过检查日志来判断是非安装成功
  ...
  return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;执行的命令是adb install -t -r [apk_path]来安装APK&lt;/p&gt;

&lt;h2 id=&quot;附录&quot;&gt;附录&lt;/h2&gt;
&lt;p&gt;flutter/packages/flutter_tools/&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;lib/src/commands/run.dart
lib/src/commands/build_apk.dart
lib/src/commands/build_aot.dart
lib/src/commands/build_bundle.dart
lib/src/commands/install.dart

lib/src/ios/devices.dart
lib/src/android/android_device.dart
lib/src/android/apk.dart
lib/src/android/gradle.dart

lib/src/base/build.dart
lib/src/bundle.dart
lib/src/compile.dart
lib/src/run_hot.dart
lib/src/resident_runner.dart
&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Sat, 07 Sep 2019 21:13:40 +0000</pubDate>
        <link>http://gityuan.com/2019/09/07/flutter_run/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/09/07/flutter_run/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>源码解读Flutter tools机制</title>
        <description>&lt;h2 id=&quot;一flutter-tools命令&quot;&gt;一、Flutter tools命令&lt;/h2&gt;

&lt;h3 id=&quot;11-概述&quot;&gt;1.1 概述&lt;/h3&gt;
&lt;p&gt;开发Flutter应用过程，经常会用过Flutter命令，比如flutter run可用于安装并运行Flutter应用，flutter build可用于构建产物，相信有不少人会好奇flutter命令背后的原理。
对于flutter命令的起点位于flutter sdk中路径/flutter/bin/目录中的flutter命令，该命令最终会调用到flutter/packages/flutter_tools工程。&lt;/p&gt;

&lt;h3 id=&quot;12-flutter命令参数表&quot;&gt;1.2 flutter命令参数表&lt;/h3&gt;

&lt;p&gt;列举Flutter命令、对应类以及说明，实现见下文[小节2.3]。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;名称&lt;/th&gt;
      &lt;th&gt;对应类&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;create&lt;/td&gt;
      &lt;td&gt;CreateCommand&lt;/td&gt;
      &lt;td&gt;创建新的Flutter项目&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;build&lt;/td&gt;
      &lt;td&gt;BuildCommand&lt;/td&gt;
      &lt;td&gt;Flutter构建命令&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;install&lt;/td&gt;
      &lt;td&gt;InstallCommand&lt;/td&gt;
      &lt;td&gt;安装Flutter应用到已连接设备&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;run&lt;/td&gt;
      &lt;td&gt;RunCommand&lt;/td&gt;
      &lt;td&gt;运行Flutter应用于已连接设备&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;packages&lt;/td&gt;
      &lt;td&gt;PackagesCommand&lt;/td&gt;
      &lt;td&gt;管理Flutter包的命令&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;devices&lt;/td&gt;
      &lt;td&gt;DevicesCommand&lt;/td&gt;
      &lt;td&gt;列出所有已连接的设备&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;emulators&lt;/td&gt;
      &lt;td&gt;EmulatorsCommand&lt;/td&gt;
      &lt;td&gt;列出，启动，创建模拟器&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;attach&lt;/td&gt;
      &lt;td&gt;AttachCommand&lt;/td&gt;
      &lt;td&gt;附加到正在运行的应用程序&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;trace&lt;/td&gt;
      &lt;td&gt;TraceCommand&lt;/td&gt;
      &lt;td&gt;开始和停止跟踪正在运行的Flutter应用程序&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;logs&lt;/td&gt;
      &lt;td&gt;LogsCommand&lt;/td&gt;
      &lt;td&gt;显示Flutter应用运行中的log&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;doctor&lt;/td&gt;
      &lt;td&gt;DoctorCommand&lt;/td&gt;
      &lt;td&gt;显示关于已安装工具的信息&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;upgrade&lt;/td&gt;
      &lt;td&gt;UpgradeCommand&lt;/td&gt;
      &lt;td&gt;升级Flutter&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;clean&lt;/td&gt;
      &lt;td&gt;CleanCommand&lt;/td&gt;
      &lt;td&gt;删除build/和.dart_tool/ 目录&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;analyze&lt;/td&gt;
      &lt;td&gt;AnalyzeCommand&lt;/td&gt;
      &lt;td&gt;分析项目Dart代码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;format&lt;/td&gt;
      &lt;td&gt;FormatCommand&lt;/td&gt;
      &lt;td&gt;格式化一个或多个dart文件&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;config&lt;/td&gt;
      &lt;td&gt;ConfigCommand&lt;/td&gt;
      &lt;td&gt;配置Flutter settings&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;drive&lt;/td&gt;
      &lt;td&gt;DriveCommand&lt;/td&gt;
      &lt;td&gt;为当前项目运行Flutter Driver测试&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;test&lt;/td&gt;
      &lt;td&gt;TestCommand&lt;/td&gt;
      &lt;td&gt;为当前项目运行Flutter 单元测试&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;另外，对于flutter build有子命令，其子命令的对应类及说明如下：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;命令&lt;/th&gt;
      &lt;th&gt;对应类&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;build aot&lt;/td&gt;
      &lt;td&gt;BuildAotCommand&lt;/td&gt;
      &lt;td&gt;构建AOT编译产物&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;build apk&lt;/td&gt;
      &lt;td&gt;BuildApkCommand&lt;/td&gt;
      &lt;td&gt;构建Android APK&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;build ios&lt;/td&gt;
      &lt;td&gt;BuildIOSCommand&lt;/td&gt;
      &lt;td&gt;构建iOS应用bundle&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;build appbundle&lt;/td&gt;
      &lt;td&gt;BuildAppBundleCommand&lt;/td&gt;
      &lt;td&gt;构建Android应用bundle&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;build bundle&lt;/td&gt;
      &lt;td&gt;BuildBundleCommand&lt;/td&gt;
      &lt;td&gt;构建Flutter assets&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;比如flutter run则执行RunCommand.runCommand()，flutter install则执行InstallCommand.runCommand()。&lt;/p&gt;

&lt;h2 id=&quot;二深入源码flutter命令&quot;&gt;二、深入源码flutter命令&lt;/h2&gt;

&lt;h3 id=&quot;21-flutter命令起点&quot;&gt;2.1 flutter命令起点&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; /flutter/bin/flutter]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;...
FLUTTER_TOOLS_DIR=&quot;$FLUTTER_ROOT/packages/flutter_tools&quot;
SNAPSHOT_PATH=&quot;$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot&quot;
STAMP_PATH=&quot;$FLUTTER_ROOT/bin/cache/flutter_tools.stamp&quot;
SCRIPT_PATH=&quot;$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart&quot;
DART_SDK_PATH=&quot;$FLUTTER_ROOT/bin/cache/dart-sdk&quot;

DART=&quot;$DART_SDK_PATH/bin/dart&quot;
PUB=&quot;$DART_SDK_PATH/bin/pub&quot;

//真正的执行逻辑
&quot;$DART&quot; $FLUTTER_TOOL_ARGS &quot;$SNAPSHOT_PATH&quot; &quot;$@&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;$DART：是指$FLUTTER_ROOT/bin/cache/dart-sdk/bin/dart；&lt;/li&gt;
  &lt;li&gt;$SNAPSHOT_PATH：是指$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot，这是由packages/flutter_tools项目编译所生成的产物文件。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;那么flutter命令等价于如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;/bin/cache/dart-sdk/bin/dart $FLUTTER_TOOL_ARGS &quot;bin/cache/flutter_tools.snapshot&quot; &quot;$@&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;dart执行flutter_tools.snapshot，其实也就是执行flutter_tools.dart的main()方法，也就是说将上述命令改为如下语句，则运行flutter命令可以执行本地flutter_tools的项目代码，可用于本地调试分析。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;/bin/cache/dart-sdk/bin/dart $FLUTTER_TOOL_ARGS &quot;$FLUTTER_ROOT/packages/flutter_tools/bin/flutter_tools.dart&quot; &quot;$@&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来，执行流程进入flutter/packages/flutter_tools/目录。&lt;/p&gt;

&lt;h3 id=&quot;22-flutter_toolsmain&quot;&gt;2.2 flutter_tools.main&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/packages/flutter_tools/bin/flutter_tools.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;import 'package:flutter_tools/executable.dart' as executable;

void main(List&amp;lt;String&amp;gt; args) {
  executable.main(args);  //[见小节2.3]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;23-executablemain&quot;&gt;2.3 executable.main&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/executable.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;import 'runner.dart' as runner;

Future&amp;lt;void&amp;gt; main(List&amp;lt;String&amp;gt; args) async {
  ...
  //[见小节2.4]
  await runner.run(args, &amp;lt;FlutterCommand&amp;gt;[
    AnalyzeCommand(verboseHelp: verboseHelp),
    AttachCommand(verboseHelp: verboseHelp),
    BuildCommand(verboseHelp: verboseHelp),
    ChannelCommand(verboseHelp: verboseHelp),
    CleanCommand(),
    ConfigCommand(verboseHelp: verboseHelp),
    CreateCommand(),
    DaemonCommand(hidden: !verboseHelp),
    DevicesCommand(),
    DoctorCommand(verbose: verbose),
    DriveCommand(),
    EmulatorsCommand(),
    FormatCommand(),
    GenerateCommand(),
    IdeConfigCommand(hidden: !verboseHelp),
    InjectPluginsCommand(hidden: !verboseHelp),
    InstallCommand(),
    LogsCommand(),
    MakeHostAppEditableCommand(),
    PackagesCommand(),
    PrecacheCommand(),
    RunCommand(verboseHelp: verboseHelp),
    ScreenshotCommand(),
    ShellCompletionCommand(),
    StopCommand(),
    TestCommand(verboseHelp: verboseHelp),
    TraceCommand(),
    TrainingCommand(),
    UpdatePackagesCommand(hidden: !verboseHelp),
    UpgradeCommand(),
    VersionCommand(),
  ], verbose: verbose,
     muteCommandLogging: muteCommandLogging,
     verboseHelp: verboseHelp,
     overrides: &amp;lt;Type, Generator&amp;gt;{
       CodeGenerator: () =&amp;gt; const BuildRunner(),
     });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;24-runnerrun&quot;&gt;2.4 runner.run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/runner.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Future&amp;lt;int&amp;gt; run(
  List&amp;lt;String&amp;gt; args,
  List&amp;lt;FlutterCommand&amp;gt; commands, {
  bool muteCommandLogging = false,
  bool verbose = false,
  bool verboseHelp = false,
  bool reportCrashes,
  String flutterVersion,
  Map&amp;lt;Type, Generator&amp;gt; overrides,
}) {
  ...
  //创建FlutterCommandRunner对象
  final FlutterCommandRunner runner = FlutterCommandRunner(verboseHelp: verboseHelp);
  //[见小节2.4.1] 将创建的命令对象都加入到_commands
  commands.forEach(runner.addCommand);

  return runInContext&amp;lt;int&amp;gt;(() async {
    ...
    // [见小节2.5]
    await runner.run(args);
    ...
  }, overrides: overrides);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;241-addcommand&quot;&gt;2.4.1 addCommand&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; package:args/command_runner.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void addCommand(Command&amp;lt;T&amp;gt; command) {
  var names = [command.name]..addAll(command.aliases);
  for (var name in names) {
    _commands[name] = command;
    argParser.addCommand(name, command.argParser);
  }
  command._runner = this;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;所有命令都加入到_commands。比如flutter run对应的命令对象为RunCommand，flutter build对应的命令对象为buildCommand。&lt;/p&gt;

&lt;h3 id=&quot;25-fluttercommandrunnerrun&quot;&gt;2.5 FlutterCommandRunner.run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/runner/flutter_command_runner.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class FlutterCommandRunner extends CommandRunner&amp;lt;void&amp;gt; {

  Future&amp;lt;void&amp;gt; run(Iterable&amp;lt;String&amp;gt; args) {
    return super.run(args); // [见小节2.6]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;26-commandrunnerrun&quot;&gt;2.6 CommandRunner.run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; package:args/command_runner.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class CommandRunner&amp;lt;T&amp;gt; {

  Future&amp;lt;T&amp;gt; run(Iterable&amp;lt;String&amp;gt; args) =&amp;gt;
      new Future.sync(() =&amp;gt; runCommand(parse(args))); //见下文

  Future&amp;lt;T&amp;gt; runCommand(ArgResults topLevelResults) async {
    var argResults = topLevelResults;
    var commands = _commands;
    Command command;
    var commandString = executableName;

    while (commands.isNotEmpty) {
      ...
      argResults = argResults.command;
      //根据命令名从命令列表中找到相应的命令
      command = commands[argResults.name];
      command._globalResults = topLevelResults;
      command._argResults = argResults;
      commands = command._subcommands;  //查找到子命令
      commandString += &quot; ${argResults.name}&quot;;
    }
    // 执行真正对应命令的run()方法 [见小节2.7]
    return (await command.run()) as T;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法会根据命令后通过循环遍历查找子命令，直到找到最后的命令为止。但这些命令都直接或者间接继承于FlutterCommand命令&lt;/p&gt;

&lt;h3 id=&quot;27-fluttercommandrun&quot;&gt;2.7 FlutterCommand.run&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/runner/flutter_command.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;abstract class FlutterCommand extends Command&amp;lt;void&amp;gt; {

  Future&amp;lt;void&amp;gt; run() {
    final DateTime startTime = systemClock.now();

    return context.run&amp;lt;void&amp;gt;(
      name: 'command',
      overrides: &amp;lt;Type, Generator&amp;gt;{FlutterCommand: () =&amp;gt; this},
      body: () async {
        ...
        try {
          // [见小节2.8]
          commandResult = await verifyThenRunCommand(commandPath);
        } on ToolExit {
          commandResult = const FlutterCommandResult(ExitStatus.fail);
          rethrow;
        } finally {
          ...
        }
      },
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;28-fluttercommandverifythenruncommand&quot;&gt;2.8 FlutterCommand.verifyThenRunCommand&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/runner/flutter_command.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;abstract class FlutterCommand extends Command&amp;lt;void&amp;gt; {

  Future&amp;lt;FlutterCommandResult&amp;gt; verifyThenRunCommand(String commandPath) async {
    await validateCommand();
    if (shouldUpdateCache) {
      await cache.updateAll(await requiredArtifacts);
    }
    if (shouldRunPub) {
      //获取pub
      await pubGet(context: PubContext.getVerifyContext(name));
      final FlutterProject project = await FlutterProject.current();
      await project.ensureReadyForPlatformSpecificTooling();
    }
    setupApplicationPackages();
    ...

    // 执行真正对应的命令类
    return await runCommand();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法先执行pubGet()用于下载pubspec.yaml里配置的依赖，该pub对应执行命令为：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;$flutterRoot/bin/cache/dart-sdk/bin/pub --verbosity=warning get --no-precompile
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最终执行真正对应的命令类的runCommand方法。如果RunCommand.runCommand()过程，见下一篇文章。&lt;/p&gt;

&lt;h2 id=&quot;附录&quot;&gt;附录&lt;/h2&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;/flutter/bin/flutter

/flutter/packages/flutter_tools/
  - bin/flutter_tools.dart
  - lib/executable.dart
  - lib/runner.dart
  - lib/src/runner/flutter_command_runner.dart
  - lib/src/runner/flutter_command.dart  (FlutterCommand是各种Command的父类)

package:args/command_runner.dart
&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Sun, 01 Sep 2019 21:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/09/01/flutter_tool/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/09/01/flutter_tool/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
      <item>
        <title>深入理解Flutter的Platform Channel机制</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;基于Flutter 1.5，从源码视角来深入剖析flutter的channel，相关源码目录见文末附录&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;一概述&quot;&gt;一、概述&lt;/h2&gt;

&lt;p&gt;Flutter 官方提供了一种 Platform Channel 的方案，用于 Dart 和平台之间相互通信。&lt;/p&gt;

&lt;p&gt;核心原理：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Flutter应用通过Platform Channel将传递的数据编码成消息的形式，跨线程发送到该应用所在的宿主(Android或iOS)；&lt;/li&gt;
  &lt;li&gt;宿主接收到Platform Channel的消息后，调用相应平台的API，也就是原生编程语言来执行相应方法；&lt;/li&gt;
  &lt;li&gt;执行完成后将结果数据通过同样方式原路返回给应用程序的Flutter部分。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;整个过程的消息和响应是异步的，所以不会直接阻塞用户界面。&lt;/p&gt;

&lt;h4 id=&quot;11-流程图&quot;&gt;1.1 流程图&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/img/method_channel/MethodChannel.jpg&quot;&gt;MethodChannel调用流程&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/method_channel/MethodChannel.jpg&quot; alt=&quot;MethodChannel&quot; /&gt;&lt;/p&gt;

&lt;p&gt;FlutterViewHandlePlatformMessage()方法会调用到Java层的FlutterJNI.handlePlatformMessage()方法。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/img/method_channel/ChannelReply.jpg&quot;&gt;MethodChannel返回流程&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/method_channel/ChannelReply.jpg&quot; alt=&quot;ChannelReply&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;12-channel类说明&quot;&gt;1.2 Channel类说明&lt;/h4&gt;

&lt;p&gt;1) Flutter提供了三种不同的Channel：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;BasicMessageChannel：传递字符串和半结构化数据&lt;/li&gt;
  &lt;li&gt;MethodChannel：方法调用&lt;/li&gt;
  &lt;li&gt;EventChannel：数据流的通信&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2) 方法编解码MethodCodec有两个子类：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;StandardMethodCodec&lt;/li&gt;
  &lt;li&gt;JSONMethodCodec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3) 消息编解码MessageCodec有4个子类：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;StandardMessageCodec&lt;/li&gt;
  &lt;li&gt;StringCodec&lt;/li&gt;
  &lt;li&gt;JSONMessageCodec&lt;/li&gt;
  &lt;li&gt;BinaryCodec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4) BinaryMessages&lt;/p&gt;

&lt;p&gt;_handlers的数据类型为map，其中以MethodChannel的name为key，以返回值为Future&lt;ByteData&gt;的Function为value。&lt;/ByteData&gt;&lt;/p&gt;

&lt;p&gt;//待完善&lt;/p&gt;

&lt;h4 id=&quot;13-实例&quot;&gt;1.3 实例&lt;/h4&gt;
&lt;p&gt;以官方提供的Android平台获取电池电量的实例，有Flutter端和Android端两部分代码。&lt;/p&gt;

&lt;p&gt;Flutter端代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _HomePageState extends State&amp;lt;HomePage&amp;gt; {
  //创建MethodChannel [见小节2.1]
  static const platform = const MethodChannel('samples.flutter.io/battery');

  Future&amp;lt;void&amp;gt; _getBatteryLevel() async {
    try {
       //调用相应通道的方法 [见小节2.2]
       int batteryLevel = await platform.invokeMethod('getBatteryLevel');
    } on PlatformException catch (e) {
      ...
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Android端代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = &quot;samples.flutter.io/battery&quot;;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建方法通道 [见小节4.1]
        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                new MethodCallHandler() {
                    public void onMethodCall(MethodCall call, Result result) {
                      if (call.method.equals(&quot;getBatteryLevel&quot;)) {
                          //调用android端的BatteryManager来获取电池电量信息
                          int batteryLevel = getBatteryLevel();
                          if (batteryLevel != -1) {
                              //将函数执行的成功结果回传到Flutter端
                              result.success(batteryLevel);   
                          } else {
                              //将函数执行的失败结果回传到Flutter端
                              result.error(&quot;UNAVAILABLE&quot;, &quot;Battery level not available.&quot;, null);
                          }
                      } else {
                          result.notImplemented();
                      }
                    }
                });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;二dart层&quot;&gt;二、Dart层&lt;/h2&gt;

&lt;h3 id=&quot;21-methodchannel初始化&quot;&gt;2.1 MethodChannel初始化&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/platform_channel.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class MethodChannel {
    //[见小节2.1.1]
    const MethodChannel(this.name, [this.codec = const StandardMethodCodec()]);
    final String name;
    final MethodCodec codec;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;默认用的是标准方法编解码器StandardMethodCodec&lt;/p&gt;

&lt;h4 id=&quot;211-standardmethodcodec初始化&quot;&gt;2.1.1 StandardMethodCodec初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/message_codecs.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class StandardMethodCodec implements MethodCodec {
  //[见小节2.1.2]
  const StandardMethodCodec([this.messageCodec = const StandardMessageCodec()]);

  final StandardMessageCodec messageCodec;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;212-standardmessagecodec初始化&quot;&gt;2.1.2 StandardMessageCodec初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/message_codecs.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class StandardMessageCodec implements MessageCodec&amp;lt;dynamic&amp;gt; {

  const StandardMessageCodec();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;22-methodchannelinvokemethod&quot;&gt;2.2 MethodChannel.invokeMethod&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/platform_channel.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class MethodChannel {

    Future&amp;lt;T&amp;gt; invokeMethod&amp;lt;T&amp;gt;(String method, [ dynamic arguments ]) async {
      //[见小节2.3]
      final ByteData result = await BinaryMessages.send(name,
          codec.encodeMethodCall(MethodCall(method, arguments)),
      );
      ...
      final T typedResult = codec.decodeEnvelope(result);
      return typedResult;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;创建MethodCall对象[小节2.2.1]；&lt;/li&gt;
  &lt;li&gt;通过StandardMethodCodec的encodeMethodCall将MethodCall转换为ByteData数据类型[小节2.2.2]；&lt;/li&gt;
  &lt;li&gt;然后调用BinaryMessages的send来发送消息[小节2.3]&lt;/li&gt;
  &lt;li&gt;最后，decodeEnvelope来解码结果&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;221-methodcall初始化&quot;&gt;2.2.1 MethodCall初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/message_codec.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class MethodCall {
  const MethodCall(this.method, [this.arguments]);
  final String method; //方法名，非空
  final dynamic arguments;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;222-encodemethodcall&quot;&gt;2.2.2 encodeMethodCall&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/message_codecs.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class StandardMethodCodec implements MethodCodec {

    ByteData encodeMethodCall(MethodCall call) {
      //创建一个用于写的buffer [见小节2.2.3]
      final WriteBuffer buffer = WriteBuffer();
      //调用StandardMessageCodec将数据写入buffer
      messageCodec.writeValue(buffer, call.method);
      messageCodec.writeValue(buffer, call.arguments);
      return buffer.done();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;223-writebuffer初始化&quot;&gt;2.2.3 WriteBuffer初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; lib/src/foundation/serialization.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class WriteBuffer {
  WriteBuffer() {
    _buffer = Uint8Buffer();
    _eightBytes = ByteData(8);
    _eightBytesAsList = _eightBytes.buffer.asUint8List();
  }

  Uint8Buffer _buffer;
  ByteData _eightBytes;
  Uint8List _eightBytesAsList;

  ByteData done() {
    final ByteData result = _buffer.buffer.asByteData(0, _buffer.lengthInBytes);
    _buffer = null;
    return result;
  }
  ...
}

&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;23-binarymessagessend&quot;&gt;2.3 BinaryMessages.send&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/platform_messages.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class BinaryMessages {

  static Future&amp;lt;ByteData&amp;gt; send(String channel, ByteData message) {
    final _MessageHandler handler = _mockHandlers[channel];
    if (handler != null)
      return handler(message);
    //[见小节2.4]
    return _sendPlatformMessage(channel, message);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;_mockHandlers是用于调试的。&lt;/p&gt;

&lt;h3 id=&quot;24-binarymessages_sendplatformmessage&quot;&gt;2.4 BinaryMessages._sendPlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; lib/src/services/platform_messages.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static Future&amp;lt;ByteData&amp;gt; _sendPlatformMessage(String channel, ByteData message) {
  //[见小节2.4.1]
  final Completer&amp;lt;ByteData&amp;gt; completer = Completer&amp;lt;ByteData&amp;gt;();
  //[见小节2.5]
  ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
    try {
      //[见小节6.6]
      completer.complete(reply);
    } catch (exception, stack) {
      ...
    }
  });
  return completer.future;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;241-completer初始化&quot;&gt;2.4.1 Completer初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;factory Completer() =&amp;gt; new _AsyncCompleter&amp;lt;T&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;242-_asynccompleter初始化&quot;&gt;2.4.2 _AsyncCompleter初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _AsyncCompleter&amp;lt;T&amp;gt; extends _Completer&amp;lt;T&amp;gt; {
  void complete([FutureOr&amp;lt;T&amp;gt; value]) {
    future._asyncComplete(value);
  }
}

abstract class _Completer&amp;lt;T&amp;gt; implements Completer&amp;lt;T&amp;gt; {
  final _Future&amp;lt;T&amp;gt; future = new _Future&amp;lt;T&amp;gt;();
  void complete([FutureOr&amp;lt;T&amp;gt; value]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;25-windowsendplatformmessage&quot;&gt;2.5 window.sendPlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/lib/ui/window.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class Window {
    void sendPlatformMessage(String name, ByteData data,
                             PlatformMessageResponseCallback callback) {
      final String error =
          _sendPlatformMessage(name, _zonedPlatformMessageResponseCallback(callback), data);
      if (error != null)
        throw new Exception(error);
    }

    //[见小节3.1]
    String _sendPlatformMessage(String name,
                            PlatformMessageResponseCallback callback,
                            ByteData data) native 'Window_sendPlatformMessage';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;251-window_zonedplatformmessageresponsecallback&quot;&gt;2.5.1 window._zonedPlatformMessageResponseCallback&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/lib/ui/window.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static PlatformMessageResponseCallback _zonedPlatformMessageResponseCallback(
                              PlatformMessageResponseCallback callback) {
  //储存在注册回调所在的zone区域
  final Zone registrationZone = Zone.current;

  return (ByteData data) {
    registrationZone.runUnaryGuarded(callback, data);
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来执行_sendPlatformMessages，这是一个native方法，会调用到Flutter引擎层。&lt;/p&gt;

&lt;h2 id=&quot;三引擎层&quot;&gt;三、引擎层&lt;/h2&gt;

&lt;h3 id=&quot;31-_sendplatformmessage&quot;&gt;3.1 _SendPlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/lib/ui/window/window.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void _SendPlatformMessage(Dart_NativeArguments args) {
  tonic::DartCallStatic(&amp;amp;SendPlatformMessage, args);
}

void Window::RegisterNatives(tonic::DartLibraryNatives* natives) {
  natives-&amp;gt;Register({
      {&quot;Window_defaultRouteName&quot;, DefaultRouteName, 1, true},
      {&quot;Window_scheduleFrame&quot;, ScheduleFrame, 1, true},
      {&quot;Window_sendPlatformMessage&quot;, _SendPlatformMessage, 4, true},
      ...
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Window.dart中的_sendPlatformMessage()最终对应于引擎层中window.cc的_SendPlatformMessage()方法，为了更好理解引擎中的调用关系，见如下&lt;strong&gt;&lt;a href=&quot;/img/flutter_boot/ClassEngine.jpg&quot;&gt;Enggine核心类图&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/flutter_boot/ClassEngine.jpg&quot; alt=&quot;ClassEngine&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;32-sendplatformmessage&quot;&gt;3.2 SendPlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/lib/ui/window/window.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Dart_Handle SendPlatformMessage(Dart_Handle window,
                                const std::string&amp;amp; name,
                                Dart_Handle callback,
                                Dart_Handle data_handle) {
  UIDartState* dart_state = UIDartState::Current();
  if (!dart_state-&amp;gt;window()) {
    return tonic::ToDart(&quot;Platform messages can only be sent from the main isolate&quot;);
  }

  fml::RefPtr&amp;lt;PlatformMessageResponse&amp;gt; response;
  if (!Dart_IsNull(callback)) {
    //PlatformMessageResponseDart对象中采用的是UITaskRunner
    response = fml::MakeRefCounted&amp;lt;PlatformMessageResponseDart&amp;gt;(
        tonic::DartPersistentValue(dart_state, callback),
        dart_state-&amp;gt;GetTaskRunners().GetUITaskRunner());
  }
  if (Dart_IsNull(data_handle)) {
    dart_state-&amp;gt;window()-&amp;gt;client()-&amp;gt;HandlePlatformMessage(
        fml::MakeRefCounted&amp;lt;PlatformMessage&amp;gt;(name, response));
  } else {
    tonic::DartByteData data(data_handle);
    const uint8_t* buffer = static_cast&amp;lt;const uint8_t*&amp;gt;(data.data());
    //[见小节3.3]
    dart_state-&amp;gt;window()-&amp;gt;client()-&amp;gt;HandlePlatformMessage(
        fml::MakeRefCounted&amp;lt;PlatformMessage&amp;gt;(
            name, std::vector&amp;lt;uint8_t&amp;gt;(buffer, buffer + data.length_in_bytes()),
            response));
  }

  return Dart_Null();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法主要功能：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;该方法是发送平台消息，则只允许从主isolate中发出，否则会跑出异常&lt;/li&gt;
  &lt;li&gt;该SendPlatformMessage方法的参数name代表是channel名，data_handle是记录待执行的方法名和参数，callback是执行后回调反馈结果数据的方法&lt;/li&gt;
  &lt;li&gt;创建PlatformMessageResponseDart对象，保存callback方法&lt;/li&gt;
  &lt;li&gt;调用RuntimeController的HandlePlatformMessage来处理平台消息&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;33-runtimecontrollerhandleplatformmessage&quot;&gt;3.3 RuntimeController::HandlePlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/runtime/runtime_controller.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void RuntimeController::HandlePlatformMessage(
    fml::RefPtr&amp;lt;PlatformMessage&amp;gt; message) {
  //[见小节3.4]
  client_.HandlePlatformMessage(std::move(message));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;34-enginehandleplatformmessage&quot;&gt;3.4 Engine::HandlePlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/common/engine.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static constexpr char kAssetChannel[] = &quot;flutter/assets&quot;;

void Engine::HandlePlatformMessage(fml::RefPtr&amp;lt;PlatformMessage&amp;gt; message) {
  if (message-&amp;gt;channel() == kAssetChannel) {
    HandleAssetPlatformMessage(std::move(message));
  } else {
    //[见小节3.5]
    delegate_.OnEngineHandlePlatformMessage(std::move(message));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;35-shellonenginehandleplatformmessage&quot;&gt;3.5 Shell::OnEngineHandlePlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/common/shell.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;constexpr char kSkiaChannel[] = &quot;flutter/skia&quot;;

void Shell::OnEngineHandlePlatformMessage(
    fml::RefPtr&amp;lt;PlatformMessage&amp;gt; message) {
  if (message-&amp;gt;channel() == kSkiaChannel) {
    HandleEngineSkiaMessage(std::move(message));
    return;
  }
  //[见小节3.6]
  task_runners_.GetPlatformTaskRunner()-&amp;gt;PostTask(
      [view = platform_view_-&amp;gt;GetWeakPtr(), message = std::move(message)]() {
        if (view) {
          view-&amp;gt;HandlePlatformMessage(std::move(message));
        }
      });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来将HandlePlatformMessage的工作交给主线程的PlatformTaskRunner来处理，对于PlatformView在Android平台的实例为PlatformViewAndroid。&lt;/p&gt;

&lt;h3 id=&quot;36-platformviewandroidhandleplatformmessage&quot;&gt;3.6 PlatformViewAndroid::HandlePlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/platform/android/platform_view_android.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void PlatformViewAndroid::HandlePlatformMessage(
    fml::RefPtr&amp;lt;flutter::PlatformMessage&amp;gt; message) {
  JNIEnv* env = fml::jni::AttachCurrentThread();
  fml::jni::ScopedJavaLocalRef&amp;lt;jobject&amp;gt; view = java_object_.get(env);

  int response_id = 0;
  if (auto response = message-&amp;gt;response()) {
    response_id = next_response_id_++;
    pending_responses_[response_id] = response; //保存response
  }
  auto java_channel = fml::jni::StringToJavaString(env, message-&amp;gt;channel());
  if (message-&amp;gt;hasData()) {
    fml::jni::ScopedJavaLocalRef&amp;lt;jbyteArray&amp;gt; message_array(
        env, env-&amp;gt;NewByteArray(message-&amp;gt;data().size()));
    env-&amp;gt;SetByteArrayRegion(
        message_array.obj(), 0, message-&amp;gt;data().size(),
        reinterpret_cast&amp;lt;const jbyte*&amp;gt;(message-&amp;gt;data().data()));
    message = nullptr;
    //[见小节3.7]
    FlutterViewHandlePlatformMessage(env, view.obj(), java_channel.obj(),
                                     message_array.obj(), response_id);
  } else {
    message = nullptr;

    FlutterViewHandlePlatformMessage(env, view.obj(), java_channel.obj(),
                                     nullptr, response_id);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;PlatformViewAndroid对象的pending_responses_是一个map数据类型，里面记录着所有的待响应的PlatformMessageResponse数据。&lt;/p&gt;

&lt;h3 id=&quot;37-flutterviewhandleplatformmessage&quot;&gt;3.7 FlutterViewHandlePlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/platform/android/platform_view_android_jni.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void FlutterViewHandlePlatformMessage(JNIEnv* env, jobject obj,
                                      jstring channel, jobject message,
                                      jint responseId) {
  env-&amp;gt;CallVoidMethod(obj, g_handle_platform_message_method, channel, message, responseId);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;g_handle_platform_message_method方法所对应的便是Java层的FlutterJNI.java中的handlePlatformMessage()方法。&lt;/p&gt;

&lt;h2 id=&quot;四宿主层&quot;&gt;四、宿主层&lt;/h2&gt;

&lt;h3 id=&quot;41-methodchannel初始化&quot;&gt;4.1 MethodChannel初始化&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; io/flutter/plugin/common/MethodChannel.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public final class MethodChannel {
    private final BinaryMessenger messenger;
    private final String name;
    private final MethodCodec codec;

    public MethodChannel(BinaryMessenger messenger, String name) {
        //创建MethodChannel
        this(messenger, name, StandardMethodCodec.INSTANCE);
    }

    public MethodChannel(BinaryMessenger messenger, String name, MethodCodec codec) {
        this.messenger = messenger;
        this.name = name;
        this.codec = codec;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;再来看看MethodChannel的成员变量messenger，是一个BinaryMessenger类型的接口，由前面[1.3]是通过getFlutterView()方法所获取的。&lt;/p&gt;

&lt;h4 id=&quot;411-flutteractivitygetflutterview&quot;&gt;4.1.1 FlutterActivity.getFlutterView&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/app/FlutterActivity.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public class FlutterActivity extends Activity implements FlutterView.Provider, PluginRegistry, ViewFactory {
    private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
    private final FlutterView.Provider viewProvider = delegate;

    public FlutterView getFlutterView() {
        return viewProvider.getFlutterView(); //[见小节4.1.2]
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;412-flutteractivitydelegategetflutterview&quot;&gt;4.1.2 FlutterActivityDelegate.getFlutterView&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/app/FlutterActivityDelegate.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public final class FlutterActivityDelegate
        implements FlutterActivityEvents, FlutterView.Provider, PluginRegistry {
    public FlutterView getFlutterView() {
        return flutterView;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处的flutterView的赋值过程是在FlutterActivityDelegate的onCreate()过程，如下所示。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void onCreate(Bundle savedInstanceState) {
    ...
    FlutterNativeView nativeView = viewFactory.createFlutterNativeView();
    flutterView = new FlutterView(activity, null, nativeView);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;42-methodchannelsetmethodcallhandler&quot;&gt;4.2 MethodChannel.setMethodCallHandler&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; io/flutter/plugin/common/MethodChannel.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public final class MethodChannel {

    public void setMethodCallHandler(final @Nullable MethodCallHandler handler) {
        //[见小节4.2.1]
        messenger.setMessageHandler(name,
            handler == null ? null : new IncomingMethodCallHandler(handler));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;此处的messenger是指FlutterView，此处的handler为IncomingMethodCallHandler。&lt;/p&gt;

&lt;h4 id=&quot;421-flutterviewsetmessagehandler&quot;&gt;4.2.1 FlutterView.setMessageHandler&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/view/FlutterView.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void setMessageHandler(String channel, BinaryMessageHandler handler) {
    //[见小节4.2.2]
    mNativeView.setMessageHandler(channel, handler);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;422-flutternativeviewsetmessagehandler&quot;&gt;4.2.2 FlutterNativeView.setMessageHandler&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; FlutterNativeView.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void setMessageHandler(String channel, BinaryMessageHandler handler) {
    //[见小节4.2.3]
    dartExecutor.setMessageHandler(channel, handler);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;423-dartexecutorsetmessagehandler&quot;&gt;4.2.3 DartExecutor.setMessageHandler&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/dart/DartExecutor.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
  //[见小节4.2.4]
  messenger.setMessageHandler(channel, handler);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;424-dartmessengersetmessagehandler&quot;&gt;4.2.4 DartMessenger.setMessageHandler&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/dart/DartMessenger.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
    private final Map&amp;lt;String, BinaryMessenger.BinaryMessageHandler&amp;gt; messageHandlers;

    public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) {
      if (handler == null) {
        messageHandlers.remove(channel);
      } else {
        //将channel和handler放入到messageHandlers
        messageHandlers.put(channel, handler);
      }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;messageHandlers记录着每一个channel所对应的handler方法。&lt;/p&gt;

&lt;p&gt;再回到[小节4.2]，可知此处handler为IncomingMethodCallHandler，初始化过程见[小节4.2.5]。&lt;/p&gt;

&lt;h4 id=&quot;425-incomingmethodcallhandler初始化&quot;&gt;4.2.5 IncomingMethodCallHandler初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/plugin/common/MethodChannel.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public final class MethodChannel {

    private final class IncomingMethodCallHandler implements BinaryMessageHandler {
        private final MethodCallHandler handler;

        IncomingMethodCallHandler(MethodCallHandler handler) {
            this.handler = handler;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;五java层&quot;&gt;五、Java层&lt;/h2&gt;

&lt;p&gt;再回到小节[3.7]FlutterViewHandlePlatformMessage方法，经过JNI将调用FlutterJNI.handlePlatformMessage()方法。&lt;/p&gt;

&lt;h3 id=&quot;51-flutterjnihandleplatformmessage&quot;&gt;5.1 FlutterJNI.handlePlatformMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;private void handlePlatformMessage(final String channel, byte[] message, final int replyId) {
  if (platformMessageHandler != null) {
    platformMessageHandler.handleMessageFromDart(channel, message, replyId);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;FlutterNativeView初始化过程，attach中会执行DartExecutor.onAttachedToJNI()来设置platformMessageHandler，其值等于DartMessenger，如下所示。&lt;/p&gt;

&lt;h4 id=&quot;511-dartexecutoronattachedtojni&quot;&gt;5.1.1 DartExecutor.onAttachedToJNI&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/dart/DartExecutor.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public class DartExecutor implements BinaryMessenger {

  private final FlutterJNI flutterJNI;
  private final DartMessenger messenger;

  public DartExecutor(@NonNull FlutterJNI flutterJNI) {
    this.flutterJNI = flutterJNI;
    //创建DartMessenger对象
    this.messenger = new DartMessenger(flutterJNI);
  }

  public void onAttachedToJNI() {
    //[见小节5.1.2]
    flutterJNI.setPlatformMessageHandler(messenger);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;512-flutterjnisetplatformmessagehandler&quot;&gt;5.1.2 FlutterJNI.setPlatformMessageHandler&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void setPlatformMessageHandler(@Nullable PlatformMessageHandler platformMessageHandler) {
  this.platformMessageHandler = platformMessageHandler;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;52-dartmessengerhandlemessagefromdart&quot;&gt;5.2 DartMessenger.handleMessageFromDart&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/dart/DartMessenger.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void handleMessageFromDart(final String channel,
                        byte[] message, final int replyId) {
  //从messageHandlers中获取handler
  BinaryMessenger.BinaryMessageHandler handler = messageHandlers.get(channel);
  if (handler != null) {
    try {
      final ByteBuffer buffer = (message == null ? null : ByteBuffer.wrap(message));
      //[见小节5.3] [见小节5.2.1]
      handler.onMessage(buffer, new Reply(flutterJNI, replyId));
    } catch (Exception ex) {
      ...
    }
  } else {
    ...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;由[小节4.2.4]可知，此处的handler为IncomingMethodCallHandler，先来看看其成员变量Reply的初始化过程。&lt;/p&gt;

&lt;h4 id=&quot;521-reply初始化&quot;&gt;5.2.1 Reply初始化&lt;/h4&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/dart/DartMessenger.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class DartMessenger implements BinaryMessenger, PlatformMessageHandler {

  private static class Reply implements BinaryMessenger.BinaryReply {
    private final FlutterJNI flutterJNI;
    private final int replyId;
    private final AtomicBoolean done = new AtomicBoolean(false);

    Reply(@NonNull FlutterJNI flutterJNI, int replyId) {
      this.flutterJNI = flutterJNI;
      this.replyId = replyId;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;53-incomingmethodcallhandleronmessage&quot;&gt;5.3 IncomingMethodCallHandler.onMessage&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; io/flutter/plugin/common/MethodChannel.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;private final class IncomingMethodCallHandler implements BinaryMessageHandler {

    public void onMessage(ByteBuffer message, final BinaryReply reply) {
        //从消息中解码出MethodCall
        final MethodCall call = codec.decodeMethodCall(message);
        try {
            //[见小节5.4]
            handler.onMethodCall(call, new Result() {
                @Override
                public void success(Object result) {
                    //[见小节6.1]
                    reply.reply(codec.encodeSuccessEnvelope(result));
                }

                @Override
                public void error(String errorCode, String errorMessage, Object errorDetails) {
                    reply.reply(codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails));
                }

                @Override
                public void notImplemented() {
                    reply.reply(null);
                }
            });
        } catch (RuntimeException e) {
            ...
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;54-methodcallhandleronmethodcall&quot;&gt;5.4 MethodCallHandler.onMethodCall&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;new MethodCallHandler() {
  public void onMethodCall(MethodCall call, Result result) {
    if (call.method.equals(&quot;getBatteryLevel&quot;)) {
        //调用android端的BatteryManager来获取电池电量信息
        int batteryLevel = getBatteryLevel();

        if (batteryLevel != -1) {
            //将结果返回
            result.success(batteryLevel);
        } else {
            result.error(&quot;UNAVAILABLE&quot;, &quot;Battery level not available.&quot;, null);
        }
    } else {
        result.notImplemented();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;当方法执行成功后，会调用result.success()方法，再回到[小节5.3]，可知会执行相对应BinaryReply.reply()方法。&lt;/p&gt;

&lt;h2 id=&quot;六回传结果&quot;&gt;六、回传结果&lt;/h2&gt;

&lt;h3 id=&quot;61-replyreply&quot;&gt;6.1 Reply.reply&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/dart/DartMessenger.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class DartMessenger implements BinaryMessenger, PlatformMessageHandler {

  private static class Reply implements BinaryMessenger.BinaryReply {
    public void reply(ByteBuffer reply) {
      if (reply == null) {
        flutterJNI.invokePlatformMessageEmptyResponseCallback(replyId);
      } else {
        //[见小节6.2]
        flutterJNI.invokePlatformMessageResponseCallback(replyId, reply, reply.position());
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;62-invokeplatformmessageresponsecallback&quot;&gt;6.2 invokePlatformMessageResponseCallback&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; io/flutter/embedding/engine/FlutterJNI.java]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;public void invokePlatformMessageResponseCallback(int responseId, ByteBuffer message, int position) {
  if (isAttached()) {
    //[见小节6.3]
    nativeInvokePlatformMessageResponseCallback(
          nativePlatformViewId, responseId, message, position);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;63-invokeplatformmessageresponsecallback&quot;&gt;6.3 InvokePlatformMessageResponseCallback&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; platform_view_android_jni.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static void InvokePlatformMessageResponseCallback(JNIEnv* env,
                                                  jobject jcaller,
                                                  jlong shell_holder,
                                                  jint responseId,
                                                  jobject message,
                                                  jint position) {
  ANDROID_SHELL_HOLDER-&amp;gt;GetPlatformView()
      -&amp;gt;InvokePlatformMessageResponseCallback(env,         //
                                              responseId,  //
                                              message,     //
                                              position     //
      );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;64-invokeplatformmessageresponsecallback&quot;&gt;6.4 InvokePlatformMessageResponseCallback&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/shell/platform/android/platform_view_android.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void PlatformViewAndroid::InvokePlatformMessageResponseCallback(
        JNIEnv* env, jint response_id,
        jobject java_response_data, jint java_response_position) {
  //从pending_responses_根据response_id来查找PlatformMessageResponse
  auto it = pending_responses_.find(response_id);
  uint8_t* response_data = static_cast&amp;lt;uint8_t*&amp;gt;(env-&amp;gt;GetDirectBufferAddress(java_response_data));
  //返回结果数据
  std::vector&amp;lt;uint8_t&amp;gt; response = std::vector&amp;lt;uint8_t&amp;gt;(response_data, response_data + java_response_position);
  auto message_response = std::move(it-&amp;gt;second);
  pending_responses_.erase(it);
  //[见小节6.5]
  message_response-&amp;gt;Complete(std::make_unique&amp;lt;fml::DataMapping&amp;gt;(std::move(response)));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;message_responsed所对应的真实类型为PlatformMessageResponseDart，赋值过程[见小节3.2]。&lt;/p&gt;

&lt;h3 id=&quot;65-complete&quot;&gt;6.5 Complete&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; flutter/lib/ui/window/platform_message_response_dart.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void PlatformMessageResponseDart::Complete(std::unique_ptr&amp;lt;fml::Mapping&amp;gt; data) {
  is_complete_ = true;
  //post到UI线程来执行
  ui_task_runner_-&amp;gt;PostTask(fml::MakeCopyable(
      [callback = std::move(callback_), data = std::move(data)]() mutable {
        std::shared_ptr&amp;lt;tonic::DartState&amp;gt; dart_state = callback.dart_state().lock();
        tonic::DartState::Scope scope(dart_state);
        Dart_Handle byte_buffer = WrapByteData(std::move(data));
        //[见小节6.6]
        tonic::DartInvoke(callback.Release(), {byte_buffer});
      }));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;到此就发生了线程切换操作，将任务post到UI线程的UITaskRunner来执行。&lt;/p&gt;

&lt;h3 id=&quot;66-dartinvoke&quot;&gt;6.6 DartInvoke&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/tonic/logging/dart_invoke.cc]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;Dart_Handle DartInvoke(Dart_Handle closure, std::initializer_list&amp;lt;Dart_Handle&amp;gt; args) {
  int argc = args.size();
  Dart_Handle* argv = const_cast&amp;lt;Dart_Handle*&amp;gt;(args.begin());
  Dart_Handle handle = Dart_InvokeClosure(closure, argc, argv);
  return handle;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该方法参数closure，也就是PlatformMessageResponseDart中的callback_，不断回溯可知所对应方法便是小节[2.4]sendPlatformMessage()的第3个参数，如下所示。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;(ByteData reply) {
  try {
    completer.complete(reply); //[见小节6.7]
  } catch (exception, stack) {
    ...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;67-_asynccompletercomplete&quot;&gt;6.7 _AsyncCompleter.complete&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _AsyncCompleter&amp;lt;T&amp;gt; extends _Completer&amp;lt;T&amp;gt; {
  void complete([FutureOr&amp;lt;T&amp;gt; value]) {
    future._asyncComplete(value);  //[见小节6.8]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;68-_future_asynccomplete&quot;&gt;6.8 _Future._asyncComplete&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _Future&amp;lt;T&amp;gt; implements Future&amp;lt;T&amp;gt; {
  void _asyncComplete(FutureOr&amp;lt;T&amp;gt; value) {
    if (value is Future&amp;lt;T&amp;gt;) {
      _chainFuture(value);
      return;
    }
    _setPendingComplete(); //设置状态为_statePendingComplete
    //[见小节6.9]
    _zone.scheduleMicrotask(() {
      _completeWithValue(value);
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;通过scheduleMicrotask()将任务封装成微任务交给UI线程&lt;/p&gt;

&lt;h3 id=&quot;69-_future_completewithvalue&quot;&gt;6.9 _Future._completeWithValue&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;void _completeWithValue(T value) {
  _FutureListener listeners = _removeListeners();
  _setValue(value);
  _propagateToListeners(this, listeners); //[见小节6.10]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;610-_future_propagatetolisteners&quot;&gt;6.10 _Future._propagateToListeners&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;static void _propagateToListeners(_Future source, _FutureListener listeners) {
  while (true) {
    ...
    //一般情况下futures只有一个监听器
    while (listeners._nextListener != null) {
      _FutureListener listener = listeners;
      listeners = listener._nextListener;
      listener._nextListener = null;
      _propagateToListeners(source, listener);
    }
    _FutureListener listener = listeners;

    //待传回的返回结果数据
    final sourceResult = source._resultOrListeners;
    if (hasError || listener.handlesValue || listener.handlesComplete) {
      Zone zone = listener._zone;
      ...
      Zone oldZone;
      if (!identical(Zone.current, zone)) {
         //当current不是该llistener所在的zone，则切换current
        oldZone = Zone._enter(zone);
      }
      ...
      void handleValueCallback() {
        //【见小节6.11】
        listenerValueOrError = listener.handleValue(sourceResult);
      }

      if (listener.handlesComplete) {
        handleWhenCompleteCallback();
      } else if (!hasError) {
        if (listener.handlesValue) {
          handleValueCallback();
        }
      } else {
        ...
      }
      if (oldZone != null) Zone._leave(oldZone);   //回到原来的zone
    }
    _Future result = listener.result;
    listeners = result._removeListeners();
    ...
    source = result;
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;611-_futurelistenerhandlevalue&quot;&gt;6.11 _FutureListener.handleValue&lt;/h3&gt;
&lt;p&gt;[-&amp;gt; third_party/dart/sdk/lib/async/future_impl.dart]&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Java&quot;&gt;class _FutureListener&amp;lt;S, T&amp;gt; {

    FutureOr&amp;lt;T&amp;gt; handleValue(S sourceResult) {
      return _zone.runUnary&amp;lt;FutureOr&amp;lt;T&amp;gt;, S&amp;gt;(_onValue, sourceResult);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;七总结&quot;&gt;七、总结&lt;/h2&gt;

&lt;p&gt;MethodChannel的执行流程涉及到主线程和UI线程的交互，代码从Dart到C++再到Java层，执行完相应逻辑后原路返回，从Java层到C++层再到Dart层。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;[小节3.5] Shell::OnEngineHandlePlatformMessage 将任务发送给主线程&lt;/li&gt;
  &lt;li&gt;[小节6.5] PlatformMessageResponseDart::Complete 将任务发送给UI线程&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 10 Aug 2019 23:15:40 +0000</pubDate>
        <link>http://gityuan.com/2019/08/10/flutter_channel/</link>
        <guid isPermaLink="true">http://gityuan.com/2019/08/10/flutter_channel/</guid>
        
        <category>flutter</category>
        
        
      </item>
    
  </channel>
</rss>
