2.6 Flutter 项目创建与运行


2.6 Flutter 项目创建与运行

本节摘要:Flutter 用一条 flutter create 命令生成项目,用 flutter run 运行。本节讲清 flutter create 的常用参数(组织名、平台、语言)、Flutter 项目的目录结构,以及首次运行与热重载的使用体验。对比上一节的 React Native,两条技术路线在"创建项目"这一步的体验差异会一目了然——Flutter 的收敛感与 RN 的多元选择形成鲜明对照。

读前必看

阅读完本节,你应当能够:

  1. 用 flutter create 创建 Flutter 项目并理解其参数含义。
  2. 说出 lib、pubspec.yaml、test 等目录的职责。
  3. 用 flutter run 运行项目并体验热重载。
  4. 对比理解 Flutter 与 React Native 项目结构的异同。

一、问题与直觉

体验过 React Native 的初始化后,再用 Flutter 你会立刻感受到一种"整齐感"。flutter create 一条命令,自动生成覆盖移动、Web、桌面的完整工程;lib 目录是唯一的代码主战场,pubspec.yaml 是唯一的配置文件。没有复杂的依赖解析过程,创建完就能跑。

这种整齐感背后是 Flutter 的设计取向:一个命令入口,一套工具链,一以贯之。它不像 RN 那样存在 Expo 与社区脚手架的分叉,官方就只给一条路。对新手来说,选择变少了,但心也定了——不用纠结走哪条路,跟着官方走就对了。

换个角度看,这也解释了为什么 Flutter 的官方文档总是"一个命令接一个命令"地讲:它的心智模型就是把"创建、运行、打包、发布"都收敛到同一个 flutter 命令上。你记住一条 flutter,就掌握了整个工程生命周期的主干。相比要记忆 npx、yarn、pod 等多个命令的 RN 生态,这确实是学习体验上的一个差异点。

二、核心原理

2.1 创建项目:一条命令与它的参数

最基础的创建:

flutter create my_first_flutter_app

命令在当前目录生成同名文件夹,内含完整项目骨架,并自动配置依赖。输出结尾会提示下一步:进入目录,运行 flutter run。

常用参数能定制工程形态:

# 指定组织名,影响 Android 包名与 iOS Bundle ID flutter create --org com.example my_app # 只生成指定平台的文件 flutter create --platforms android,ios my_mobile_app # 指定 Android 用 Java、iOS 用 Objective-C flutter create --android-language java --ios-language objc my_legacy_app

--org 参数值得重视。它决定了应用的包名前缀,直接影响应用商店的唯一性。早期不规划好,上线后改包名是件麻烦事。新项目建议一开始就用公司域名的反写形式,比如 com.example。

--platforms 参数。默认会为所有支持的平台生成文件(Android、iOS、Web、Windows、macOS、Linux)。如果只想做移动端,指定 android,ios 能减少冗余文件,项目更清爽。这是很多新手不知道的小技巧。

2.2 项目结构:一眼看懂的整齐

2.2 项目结构:一眼看懂的整齐

与 React Native 的双层结构对比:RN 把"开发层"与"原生层"的边界画得很清,Flutter 则把代码集中在 lib、把平台工程整整齐齐排在旁边。两种排布风格不同,但"代码层 + 平台层"的总框架是一致的。

2.3 核心文件:main.dart 与 pubspec.yaml

lib/main.dart 是应用入口,包含 main 函数与根 Widget。默认生成的是计数器示例应用,第 3 章我们会从这里开始改造。pubspec.yaml 是 Flutter 的"package.json",声明项目信息、依赖、资源。加第三方库就在这里,保存后跑 flutter pub get 拉取。

void main() { runApp(const MyApp()); }

main 函数调用 runApp 把根 Widget 挂到应用上——这是每个 Flutter 应用的起点。

2.3.1 pubspec.yaml 的结构一眼看

pubspec.yaml 是 Flutter 项目里最常打交道的配置文件,值得现在就把它的结构看清楚。它通常包含这几段:

段落 作用 什么时候改
name 项目名 创建时自动生成
description 项目描述 需要时
environment Dart SDK 版本约束 升级依赖时
dependencies 运行依赖 加第三方库时
dev_dependencies 开发期依赖 加测试工具时
flutter 段 资源、字体、插件配置 用到资源时

加一个网络请求库的典型操作是:在 dependencies 段加一行"库名: 版本号",保存后跑 flutter pub get。版本号写法类似 ^1.0.0 这种带脱字符的兼容区间。这里最容易踩的坑是版本号写死或与 SDK 不兼容,报错信息里通常会给出建议版本。

2.3.2 test 目录:写测试的起点

Flutter 项目默认带一个 test 目录与示例测试文件(widget_test.dart)。这是 Flutter 相比 RN 脚手架更"一步到位"的地方——测试基础设施默认就搭好了。第 6 章讲工程实践时我们会真正写测试,现在只要知道:这个目录放的是自动化测试,Widget 测试能在不启动应用的情况下验证界面行为。养成"功能写完顺手补个测试"的习惯,是从初级到中级的标志之一。

三、工程实践要点

3.1 运行与热重载

创建完项目,运行:

cd my_first_flutter_app flutter run

首次运行要编译引擎并下载依赖,耗时偏长。启动后,模拟器或设备上会出现默认的计数器应用——点击按钮数字加一,这是 Flutter 的经典"hello world"。

热重载的使用。运行中修改代码并保存,按 r 触发热重载(保留状态、秒级生效),按 R 热重启(清状态重跑)。这是 Flutter 开发最直观的爽点:改样式、调布局、看效果,全在几秒内完成。

3.2 两框架创建流程对比

环节 React Native Flutter
创建命令 脚手架或 Expo flutter create
入口文件 index.js 与 App.js lib/main.dart
配置文件 package.json pubspec.yaml
原生工程 android 与 ios 移动、Web、桌面全生成
运行命令 run-android / run-ios flutter run
热重载 快速刷新 热重载与热重启

这张表帮你把两套流程装进同一个框架:概念是对应的(入口、配置、原生工程、运行、热重载),只是名字和位置不同。掌握了这种"同构对应"的观察方式,后续章节的双框架对照会越来越顺。

3.2.1 热重载与热重启到底怎么选

热重载(Hot Reload)和热重启(Hot Restart)是 Flutter 的两个高频操作,功能不同,用错会浪费调试时间。

热重载(r):把最新代码注入运行中的应用,保留当前状态。适用于修改 UI、样式、布局这类不影响应用整体结构的改动——你改个颜色、调个间距,按 r,立刻看到效果,页面上的状态(比如登录表单)还在。

热重启(R):重新启动应用,清空状态。适用于改了 main 函数、应用整体结构或初始化逻辑的情况——这类改动影响应用启动流程,热重载无法正确处理,需要重启。

简单记忆法:改界面用 r,改逻辑骨架用 R。实际开发中九成是 r,偶尔遇到"改了没反应",先试试 R 再考虑其他排查。这个判断逻辑在 React Native 的快速刷新里也有类似体现——凡是改到应用入口层级的代码,刷新行为就会退化成完整重启。

3.2.2 从终端输出读信息

flutter run 的终端输出很有信息量。启动时它会列出可用的设备、当前运行的目标平台;运行中快捷键提示(r、R、q 等)会印在终端里;崩溃时堆栈会直接输出。养成"先看终端再猜原因"的习惯,能省掉大量无头绪的排查。特别是一开始没记住快捷键时,终端里就有提示——这也是 Flutter 官方设计得比较贴心的一个点。

⚠️ 常见坑:pubspec.yaml 缩进写错导致依赖解析失败。YAML 对缩进极其敏感,多加依赖时务必保持层级一致。
💡 关键直觉:flutter run 第一次慢、后续快,是因为首次要编译。跑起来之后按 r 热重载,几乎所有 UI 改动都在几秒内生效,这是 Flutter 开发的节奏感所在。

3.3 成功之后第一件事

看到计数器应用跑起来后,把 main.dart 里的文字改一改,保存,按 r 热重载,观察界面变化。然后对照 2.2 节的目录结构图,把每个目录的实际内容翻一遍。最后对比一下上一节建好的 React Native 项目,看看两边的入口、配置、平台目录分别长什么样。这个对比做完,你就同时对两个框架的工程有了真实体感。

FAQ:Flutter 项目的常见疑问

问:flutter create 默认生成那么多平台目录,会不会拖慢运行? 不会。只有你主动运行到某个平台时,对应的目录才被编译。多余的目录只是文件存在,不影响开发速度。不过如果确定只做移动端,用 --platforms android,ios 创建会更干净。

问:项目名有什么讲究? 项目名会作为包名与目录名的一部分,建议用全小写加下划线(比如 my_app),不要用大写或连字符。Dart 的包名规范就是这么要求的,不规范的名字可能在发布或导入时报错。

问:改完 pubspec.yaml 后需要做什么? 保存后运行 flutter pub get 拉取新依赖。很多新手改完配置发现"代码里引用不了新库",就是忘了这一步。VS Code 里装了 Flutter 扩展后,保存 pubspec.yaml 通常会自动触发,但手动跑一次更稳妥。

问:flutter run 之后界面卡住没反应? 常见原因是首次编译耗时较长,或模拟器性能不足。确认模拟器已启动、等待首次编译完成;如果一直卡住,重启模拟器与终端再试。热重载卡住时,按 R 热重启通常能恢复。

3.4 关于 flutter doctor 的补充使用

flutter doctor 不止在安装后跑一次,它应该是你遇到环境问题时的"第一站"。当 flutter run 报出莫名错误时,先跑一遍 flutter doctor,看它是否能定位到某个组件缺失或版本问题。它的输出结构是固定的:Flutter 工具链、Android 工具链、iOS 工具链(macOS)、IDE 插件、设备检测。任何一项出现叉号,都可能是你当前问题的根源。把 flutter doctor 当作环境体检仪,而不是安装仪式,它的价值会大得多。

3.5 从创建到发布的一小步

本书只覆盖到"创建与运行",但值得提前知道后续还有哪几步:flutter build 构建发布包、配置应用图标与名称、签名与上架。这些步骤在官方文档里都有完整指引,本章不展开。提前了解的目的是让你对"flutter 命令体系"有个全貌——create 是出生,run 是成长,build 是成年。理解这个全貌,学后面的内容时就知道每块知识处在工程生命周期的哪个位置。

3.6 一句话总结本节与 RN 的差异

把第 2.5 与 2.6 两节并排看,两套框架"创建项目"的差异可以浓缩成一句:RN 需要你先选路线(Expo 还是社区脚手架),Flutter 没有选择,只有一条官方路径。这个差异背后是两套生态哲学的映射——RN 拥抱多元选择,Flutter 追求统一体验。没有优劣,但理解这个差异,你在两套框架间切换时会少很多"为什么它不这样"的困惑。工程工具没有绝对正确,只有"是否匹配团队习惯与项目约束"。

核心回顾

  • 创建命令:flutter create 一条命令生成完整工程,参数控制组织名、平台与语言。
  • --org 参数:影响包名与 Bundle ID,新项目尽早规划。
  • 目录结构:lib 是代码主战场,pubspec.yaml 是配置中心,平台目录默认全生成。
  • pubspec 结构:dependencies 与 dev_dependencies 区分运行与开发依赖,版本用兼容区间。
  • 入口机制:main 函数调 runApp 挂根 Widget,是每个应用起点。
  • 运行流程:flutter run 跑起应用,r 热重载、R 热重启、q 退出。
  • 热重载选择:改界面用 r(保留状态),改结构骨架用 R(清状态)。
  • 双框架对应:RN 的 package.json 对应 Flutter 的 pubspec.yaml,入口与平台目录一一对应。
  • YAML 敏感:pubspec.yaml 缩进错误会导致依赖解析失败。

两个框架的第一个项目都跑起来了,代码的世界正式打开。下一章进入核心语言与声明式 UI 范式——先看懂 JSX 与 Dart,再看状态如何驱动界面。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U