[Flutter] Flutter 的 build 系统
Posted bug樱樱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Flutter] Flutter 的 build 系统相关的知识,希望对你有一定的参考价值。
前言
对于Flutter开发者来说,build_runner 可以说并不是一个陌生的东西,很多package中就要求调用build_runner 来自动生成处理代码,比如说json_serializable;
但正如其描述中所述的那样,其是通过 Dart Build System来实现的,build_runner 和其又是一个什么关系,接下来就来学习一下dart的build系统
dart 的 build 系统
组成
dart 的 build系统,由 build_config、 build_modules、build_resolvers、 build_runner、 build_test、 build_web_compilers 共同组合、完成了dart 的 build 系统;
- build_config 就是解析那个build.yaml文件,用来配置build_runner,没什么好说的,具体的功能后面再细说;
- build_modules 好像是解析module级别信息的一个库
- build_resolvers 从自述文件中分析,好像是一个给build_runner 每步提供所需信息的解析器?
- build_runner 整个build系统的核心部分,其他部分都是为了拓展和实现此功能而存在的;
- build_test 字面意思,一个测试库;
- build_web_compilers 用于web端的build系统;
作用
Flutter的build系统其实就是生成代码,对标的应该是JAVA的APT这块的东西;
另外,对于 dart 的 build 系统,官方是有这么一段介绍:
Although the Dart build system is a good alternative to reflection (which has performance issues) and macros (which Dart’s compilers don’t support), it can do more than just read and write Dart code. For example, the sass_builder package implements a builder that generates
.css
files from.scss
and.sass
files.
也就是说dart build理论上是可以来做很多人心心念念的反射的;
基本使用
如果仅仅是使用方面来说,build_runner 的使用非常简单;比如说我们最常用的一条命令就是:
flutter pub run build_runner build
也可以配置build.yaml来修改配置信息,生成符合需要的代码;
不过在输入上面那句build_runner build之后发生了什么,像build_config之类的在这个过程中各自起了什么作用,这就需要追踪一下;
build_runner 都干了什么
根据日志信息,build_runner 的流程基本遵循这样一个套路:
- 生成和预编译build脚本
- 处理输入环境和资源
- 根据前面的脚本和输入信息,开始正式执行builder生成代码;
- 缓存信息,用于下一回生成代码的时候增量判断使用;
接下来就看下这些编译脚本、输入环境、资源等不知所云的东西,到底是什么;
生成和预编译build脚本
生成部分:
首先来到build_runner的main函数部分,前面一大片对参数检测的拦截判断,真正执行命令的地方放在了最后:
在这个方法中最先做的事就是生成build脚本
其内容也很简单,说白了就是输出一个文件而已:
至于这个文件内容是什么,有什么用,先放到后面再说;现在先关注于整体流程;
那么现在可以得知,这步会在scriptLocaton这个路径上生成一个build脚本;而这个路径也不难得到:
其实就是 .dart_tool/build/entrypoint/build.dart 这个文件;
预编译部分:
在上面贴的generateAndRun方法中,生成文件之后就会执行一个 _createKernelIfNeeded
方法,其作用也正如其名,检测是否需要就创建内核文件;
而这个内核文件,也就是后缀为build.dart.dill 文件
同时,在这里也提到了一个新的概念:assetGraph
,不过这些也是后面再细看的东西;
处理输入环境和资源
在编译完build脚本生成内核后,下面就是执行这个内核文件;在这里新开了一个isolate去执行这个文件:
接下来就该看下这个内核文件到底是什么……但是呢,内核文件这东西,本来就不是给人看的………………所以呢,可以从另一方面考虑下,比如说,既然内核文件看不了,那我就看内核文件的从哪编译来的,反正逻辑上也是大差不差,完全可以参考;
正好内核文件的来源,也就是那个build脚本,其位置在上面也提到过了;在我测试代码中,它最后是这样的:
其中的这个_i10,正是build_runner……看来兜兜转转又回来了?
应该说回来了,但没完全回来,上面提到的build_runner是bin目录下的;这次的build_runner是lib目录下的,入口还是不一样的;
在这里,build_runner build中的build这个参数才真正识别并开始执行;前面都是前戏;而执行这个build命令的是一个名为BuildCommandRunner
的类,其内部内置了包括build在内的诸多函数命令:
由于测试的指令参数为build,所以命中的commend为 BuildCommand
;而 BuildCommand 所做的事也基本集中在 src/generate/build.dart 这个文件中的build方法中了;自此开始真正去执行build_runner对应Builder中要求做的事;
其build方法所做的事还是比较容易看懂的:
- 配置环境(包括输入输出配置)
- 配置通用选项(build时候的配置项目)
- 调用BuildRunner.create创建Builder和生成所需数据,最后调用run执行;
而这部分所说的处理输入环境和资源就在 BuildRunner.create
这部分中;其会调用 BuildDefinition.prepareWorkspace
方法;
而在这里就出现了上面提到的assetGraph
,这里就是其创建和使用的地方:
所以,最终总结一下,处理输入环境和资源 这个环节所做的事就是根据配置生成输入输出、build过程中所需的各种参数,提供assetGraph这个东西;
具体这些配置入口在哪,从何而来,assetGraph又是什么东西,有什么作用,后面再看;
正式执行builder生成代码
这部分就是刚才提到的调用run方法的地方;
它的run方法咋看好像也不难懂的样子,主要是各种新名词有点多:
不过现在只跟随build流程来说的话,核心应该事其中的_safeBuild
方法:
其所做的事,除了各种心跳log之外,应该就是更新assetGraph;执行_runPhases
;另外毕竟事safeBuild嘛,所以新开了一个zone来处理;
_runPhases
所做的事就是真正去执行build所做的事,生成代码之类的;比如说json_serializable中的build,就会走_runBuilder
部分并最终调用runBuilder
中的builder.build
,也就是自定义Builder中需要自己实现的部分;
对了,关于像json_serializable的自定义Builder从何而来的问题,答案是一开始就已经集成进来了,在builder.dart中已经出现了其身影:
不过为什么build.dart 能得知具体有哪些builder?比如说json_serializable中的builder,是怎么加入到build.dart中的,那也是后面要看的东西;
缓存信息
再次回到 _safeBuild
这块,缓存信息的部分紧贴着run部分:
好像就写了一下文件,没了?
结语
这篇大体粗略的过了一下build这个命令都干了什么;不过像生成的文件内部结构、作用;配置信息来源,如何解析之类的问题还未解决;在后面会依次看看;
最后尝试实现一份自己的自定义Builder;
作者:lwlizhe
链接:https://juejin.cn/post/7133488621180420126
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
一、架构师筑基必备技能
1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……
二、Android百大框架源码解析
1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程
三、Android性能优化实战解析
- 腾讯Bugly:对字符串匹配算法的一点理解
- 爱奇艺:安卓APP崩溃捕获方案——xCrash
- 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
- 百度APP技术:Android H5首屏优化实践
- 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
- 携程:从智行 Android 项目看组件化架构实践
- 网易新闻构建优化:如何让你的构建速度“势如闪电”?
- …
四、高级kotlin强化实战
1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》
-
从一个膜拜大神的 Demo 开始
-
Kotlin 写 Gradle 脚本是一种什么体验?
-
Kotlin 编程的三重境界
-
Kotlin 高阶函数
-
Kotlin 泛型
-
Kotlin 扩展
-
Kotlin 委托
-
协程“不为人知”的调试技巧
-
图解协程:suspend
五、Android高级UI开源框架进阶解密
1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
六、NDK模块开发
1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习
七、Flutter技术进阶
1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)
…
八、微信小程序开发
1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓
以上是关于[Flutter] Flutter 的 build 系统的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 在执行 Flutter build ios 后卡在 Building Dart 代码上
在 Flutter 中发布的“flutter build apk”出现错误
如何解决flutter gradle build error?C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 991
Flutter:build/app/outputs下的apk/release目录和flutter-apk目录有啥区别?