全栈开发知识库

01 概览与环境搭建

1.1 Flutter 是什么

Flutter 是 Google 开源的跨平台 UI 框架。一套 Dart 代码,可以编译成 Android、iOS、Web、Windows、macOS、Linux 应用;社区分支 Flutter OH 还支持 OpenHarmony / HarmonyOS NEXT(鸿蒙)。

它的核心特点是“自绘”:

  • 不把 Dart 组件翻译成原生控件(React Native 是这么做的),而是由 Flutter Engine 直接通过 GPU(Vulkan / Metal / OpenGL ES)把每一个像素画到平台提供的一块 Surface 上。
  • 因此各平台 UI 像素级一致,不受系统控件版本影响;代价是包里要带一个渲染引擎(Android 上约 +4~6MB),并且要和原生控件混排时需要额外机制(PlatformView)。

1.2 与其他方案对比

维度 Android 原生 (View/Compose) Flutter React Native KMP + Compose Multiplatform
语言 Kotlin/Java Dart JS/TS Kotlin
UI 渲染 系统 View / Compose(Skia/HWUI) 自绘(Impeller/Skia) 原生控件(Fabric) 自绘(Skia),Android 端用原生 Compose
跨端一致性 — 极高 中(控件随平台) 高
性能 最好 接近原生,AOT 编译 比 Flutter 弱,JSI 后改善 接近原生
鸿蒙支持 无 社区 Flutter OH,较成熟 社区 RNOH 社区在做,较早期
生态 最大 pub.dev,较大 npm,大 较小,快速增长
动态化 插件化/热修 官方不支持代码下发(AOT),可用 Shorebird 等 支持 bundle 下发 不支持

选择建议:业务以 UI 为主、需要三端(含鸿蒙)一致、团队愿意学 Dart,选 Flutter;强依赖动态下发选 RN;只想复用逻辑层选 KMP。

1.3 心智模型对照(Android → Flutter)

Android Flutter 说明
Activity / Fragment Route / Page(一个 Widget) Flutter 默认只有一个 FlutterActivity,页面切换在 Flutter 内部完成
View / ViewGroup Widget Widget 是不可变的配置描述,不是真正的视图对象
XML 布局 Dart 代码嵌套 Widget 没有 XML,类似 Compose
findViewById + 改属性 改 state,调用 setState 重建 声明式
RecyclerView + Adapter ListView.builder 自带懒加载与回收
LinearLayout Row / Column
FrameLayout Stack
ConstraintLayout 无直接对应,组合 Row/Column/Stack/Expanded/Align
res/drawable、res/values assets/ + pubspec.yaml 声明
Gradle 依赖 pubspec.yaml 依赖,来源 pub.dev
Intent / startActivity Navigator.push / context.go()
Handler / Looper / 协程 Future、async/await、Stream、Isolate Dart 单线程事件循环
ViewModel + LiveData/Flow ChangeNotifier / Riverpod / Bloc + Stream
SharedPreferences shared_preferences 插件 底层就是调 Android 的 SharedPreferences
Room sqflite / drift
Retrofit + OkHttp dio / http + retrofit(dart)
Glide Image.network + cached_network_image
JNI dart:ffi 直接调 C,比 JNI 简单
onCreate/onResume initState / AppLifecycleListener

1.4 环境搭建(macOS 为例)

1.4.1 安装 Flutter SDK

推荐用 FVM 管理多版本(官方 Flutter 和鸿蒙 Flutter OH 需要并存):

# 方式一:直接 git clone(简单)
git clone https://github.com/flutter/flutter.git -b stable ~/sdk/flutter
echo 'export PATH="$HOME/sdk/flutter/bin:$PATH"' >> ~/.zshrc

# 国内镜像(官方提供),网络慢时设置
echo 'export PUB_HOSTED_URL=https://pub.flutter-io.cn' >> ~/.zshrc
echo 'export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn' >> ~/.zshrc
source ~/.zshrc

# 方式二:FVM(推荐团队使用,项目内锁定版本)
brew tap leoafarias/fvm && brew install fvm
fvm install stable
cd your_project && fvm use stable   # 生成 .fvmrc,项目锁版本

1.4.2 检查环境

flutter doctor -v

逐项解决 doctor 的报错:

  • Android toolchain:使用已有的 Android SDK。若提示 license,执行 flutter doctor --android-licenses。需要 JDK 17+(Flutter 3.47 最低要求 Java 17)。
  • Xcode(仅 macOS,做 iOS 需要):App Store 安装 Xcode,然后 sudo xcode-select -s /Applications/Xcode.app && sudo xcodebuild -runFirstLaunch。Flutter 3.44 起 iOS 默认用 Swift Package Manager,不再强制安装 CocoaPods。
  • IDE:Android Studio 安装 Flutter 插件(会自动装 Dart 插件);或 VS Code 安装 Flutter 扩展。

1.4.3 创建并运行第一个工程

flutter create --org com.example --platforms android,ios flutter_playground
cd flutter_playground
flutter devices          # 列出设备(真机/模拟器)
flutter run              # 默认 debug 模式,支持热重载

运行后在终端按:

  • r:Hot Reload(热重载,保留状态,约 1 秒内生效)
  • R:Hot Restart(重启 Dart 层,状态丢失,不重装 APK)
  • q:退出

Android Studio 中点工具栏的闪电图标就是 Hot Reload。

1.5 工程结构

flutter_playground/
├── pubspec.yaml          # ≈ build.gradle:依赖、资源、版本号
├── pubspec.lock          # 依赖锁定(应用工程要提交到 git)
├── analysis_options.yaml # lint 规则 ≈ lint.xml / detekt
├── lib/                  # Dart 源码,入口 lib/main.dart
├── test/                 # 单元测试 / Widget 测试
├── assets/               # 自建,图片/字体/json 等资源
├── android/              # 一个标准 Android Gradle 工程(宿主壳)
│   └── app/src/main/kotlin/.../MainActivity.kt   # 继承 FlutterActivity
├── ios/                  # Xcode 工程(宿主壳)
└── ohos/                 # 鸿蒙宿主工程(使用 Flutter OH 时才有)

android/ 目录你会非常熟悉:它就是普通 Gradle 工程,Flutter 通过 dev.flutter.flutter-gradle-plugin 在构建时把 Dart 代码编译产物(libapp.so)和引擎(libflutter.so)打进 APK。

pubspec.yaml 示例

name: flutter_playground
description: Demo
publish_to: 'none'          # 应用不发布到 pub.dev
version: 1.0.0+1            # versionName+versionCode

environment:
  sdk: ^3.9.0

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.7.0               # 版本约束:^5.7.0 表示 >=5.7.0 <6.0.0
  go_router: ^16.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^6.0.0

flutter:
  uses-material-design: true
  assets:
    - assets/images/
  fonts:
    - family: MyFont
      fonts:
        - asset: assets/fonts/MyFont-Regular.ttf

上面依赖的版本号仅作示意,实际以 flutter pub add dio 生成的为准。

常用命令:

flutter pub add dio           # 添加依赖(自动写入 pubspec)
flutter pub get               # ≈ Gradle sync
flutter pub upgrade --major-versions
flutter pub outdated          # 查看可升级依赖
flutter clean                 # 清理构建缓存
flutter analyze               # 静态检查
flutter test                  # 跑测试
flutter build apk --release   # 出包;还有 appbundle / ipa / hap

1.6 第一个程序解读

import 'package:flutter/material.dart';

// 入口,等价于 Application + 启动 Activity
void main() {
  runApp(const MyApp());
}

// 无状态组件:只依赖构造参数
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(            // 提供主题、路由、本地化等
      title: 'Demo',
      theme: ThemeData(colorSchemeSeed: Colors.blue),
      home: const CounterPage(),
    );
  }
}

// 有状态组件:Widget 本身不可变,可变状态放在 State 里
class CounterPage extends StatefulWidget {
  const CounterPage({super.key});

  @override
  State<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  int _count = 0;  // 下划线开头 = 库私有

  @override
  Widget build(BuildContext context) {
    return Scaffold(              // ≈ 带 Toolbar/FAB 的页面骨架
      appBar: AppBar(title: const Text('计数器')),
      body: Center(child: Text('点击了 $_count 次')),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(() => _count++),  // 标记脏 → 下一帧重建
        child: const Icon(Icons.add),
      ),
    );
  }
}

关键点:

  • setState 不是“立刻刷新”,而是把当前 Element 标记为 dirty,下一帧(VSync 到来时)重新调用 build。
  • build 会被频繁调用(每帧都可能),所以里面不能做耗时操作,也不要在里面创建 Controller、发网络请求。
  • const 构造的 Widget 在编译期创建,重建时被跳过,是最基础的性能优化。

动手练习

  1. 安装环境,flutter doctor 全绿(iOS 项可选)。
  2. 创建工程,在真机运行计数器,修改文字颜色后按 r 体验热重载,再按 R 观察计数被清零。
  3. 打开 android/app/build.gradle(.kts) 和 MainActivity.kt,找到 applicationId、minSdk,对照你熟悉的 Android 工程。
  4. 执行 flutter build apk --release --split-per-abi,用 Android Studio 的 APK Analyzer 打开产物,找到 libflutter.so、libapp.so、flutter_assets/。
本页由 Markdown 自动渲染 · 共 628 篇笔记