























今天在 GitHub Trending 上看到一个有意思的项目:Flutter,这是 Google 推出的 SDK,可以用单一代码库构建移动、Web 和桌面端的精美高性能用户体验。
Flutter 是 Google 开发的 UI 框架,允许开发者从单个代码库为 iOS、Android、Web、Windows、macOS 和 Linux 构建原生应用。自 2017 年首次发布以来,Flutter 已成为最流行的跨平台框架之一。
核心特性:
项目数据:
Flutter 的核心设计哲学是"Everything is a Widget"。其架构分为三层:
┌─────────────────────────────────────┐
│ Framework (Dart) │ ← Widgets, Rendering, Foundation
├─────────────────────────────────────┤
│ Engine (C++ / Skia / Impeller) │ ← 图形渲染、文本排版、Dart VM
├─────────────────────────────────────┤
│ Platform Embedder (Platform API) │ ← iOS / Android / Windows 嵌入层
└─────────────────────────────────────┘
Flutter 使用 Dart 语言,其编译策略根据目标平台不同:
| 平台 | 编译目标 | 优化方式 |
|---|---|---|
| iOS / Android | ARM 32/64 位机器码 | AOT 编译 |
| Web | JavaScript / Wasm | 编译为 JS 或 WebAssembly |
| 桌面(Windows/macOS/Linux) | Intel x64 / ARM 机器码 | AOT 编译 |
JIT vs AOT:
Flutter 正在从 Skia 迁移到 Impeller 渲染引擎,解决 Skia 的着色器编译卡顿问题:
// Impeller 核心设计
// 1. 预编译着色器(离线编译,避免运行时卡顿)
// 2. 显式图形 API 使用(Vulkan / Metal / OpenGL)
// 3. 录制式绘图命令(Display List)
Impeller 在引擎启动时就编译好所有着色器,从根本上解决了"首帧卡顿"问题。
Hot Reload 的核心流程:
build 方法// 示例:Hot Reload 保留状态
int counter = 0; // 这个值在 Hot Reload 后保持不变
void increment() {
setState(() {
counter++; // UI 更新,但 counter 值不丢失
});
}
方式一:从官网下载(推荐)
# 1. 访问 https://docs.flutter.dev/get-started
# 2. 下载对应平台的 Flutter SDK 压缩包
# 3. 解压到目标目录(如 ~/development/flutter)
方式二:从 GitHub Clone(获取最新代码)
git clone https://github.com/flutter/flutter.git -b stable
export PATH="$PATH:`pwd`/flutter/bin"
flutter doctor
创建新项目并运行:
# 创建新项目
flutter create my_app
cd my_app
# 连接设备或启动模拟器后运行
flutter run
lib/main.dart 默认内容:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
Flutter UI = Widget 树,以下是最常用的布局模式:
// 常见布局结构
Scaffold(
appBar: AppBar(title: const Text('标题')),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) => ListTile(
title: Text('Item $index'),
),
),
),
const BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
],
),
],
),
)
Flutter 提供多种状态管理方案:
| 方案 | 适用场景 | 复杂度 |
|---|---|---|
| setState | 局部状态 | ⭐ |
| InheritedWidget | 跨组件共享 | ⭐⭐ |
| Provider | 中大型应用 | ⭐⭐⭐ |
| Riverpod | 现代推荐方案 | ⭐⭐⭐ |
| Bloc | 复杂业务逻辑 | ⭐⭐⭐⭐ |
Provider 示例:
// 定义状态模型
class CounterModel with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知依赖此模型的 Widget 重建
}
}
// 在 Widget 树中提供状态
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MyApp(),
);
// 消费状态
Consumer<CounterModel>(
builder: (context, model, child) => Text('${model.count}'),
);
当需要调用平台原生 API 时,使用 Platform Channels:
Dart 端:
import 'package:flutter/services.dart';
static const platform = MethodChannel('samples.flutter.dev/battery');
Future<void> getBatteryLevel() async {
try {
final result = await platform.invokeMethod<int>('getBatteryLevel');
print('电池电量: $result%');
} on PlatformException catch (e) {
print("Failed to get battery level: '${e.message}'.");
}
}
iOS(Swift)端:
@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller = window?.rootViewController as! FlutterViewController
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery",
binaryMessenger: controller.binaryMessenger)
batteryChannel.setMethodCallHandler { call, result in
if call.method == "getBatteryLevel" {
result(Int(UIDevice.current.batteryLevel * 100))
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Flutter 支持编译为 Web 应用:
# 编译为 Web 版本(默认 JavaScript)
flutter build web
# 实验性:编译为 WebAssembly(性能更佳)
flutter build web --wasm
Web 平台使用 CanvasKit(基于 WebGL)或 HTML 渲染后端。
flutter doctor 报错:缺少 Android toolchain问题: 运行 flutter doctor 提示 Android license status unknown。
解决方案:
# 接受 Android SDK 许可
flutter doctor --android-licenses
# 如果仍然失败,检查 ANDROID_HOME 环境变量
export ANDROID_HOME=$HOME/Library/Android/sdk # macOS
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
问题: pod install 失败或版本冲突。
解决方案:
# 确保 CocoaPods 已安装
sudo gem install cocoapods
pod setup
# 进入 iOS 目录重新安装
cd ios
pod deintegrate
pod install --repo-update
问题: 首次运行动画时卡顿(Skia 着色器编译导致)。
解决方案:
// iOS: 在 Info.plist 中添加
<key>FLTEnableImpeller</key>
<true/>
// Android: 在 AndroidManifest.xml 中添加
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="true" />
问题: flutter pub get 报版本冲突。
解决方案:
# 使用 dependency override 强制指定版本
dependency_overrides:
http: ^1.0.0
或使用 flutter pub upgrade 升级所有依赖到兼容版本。
问题: Flutter Web 应用初始加载时间过长。
解决方案:
flutter build web --release --web-renderer canvaskitimport 'package:my_app/heavy_module.dart' deferred as heavy;
Future<void> loadHeavyModule() async {
await heavy.loadLibrary();
heavy.show();
}
Flutter 通过自绘引擎架构和 Dart 语言的多平台编译能力,真正实现了"一次编写,多端运行"的承诺。其核心价值在于:
对于新项目,Flutter 是目前跨平台方案中最值得考虑的选择。随着 Impeller 渲染引擎的全面落地和 WebAssembly 支持的成熟,Flutter 的性能优势还将进一步扩大。
相关资源:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。