跨平台方案 — 知识详解
更新: 5/15/2026 字数: 0 字 时长: 0 分钟
1. Flutter
1.1 架构
┌─────────────────────────────┐
│ Dart Framework │ Widget / Rendering / Animation / Gestures
├─────────────────────────────┤
│ Engine (C++) │ Skia 渲染 / Dart VM / Platform Channel
├─────────────────────────────┤
│ Embedder │ 平台嵌入层(Android: FlutterActivity/FlutterView)
└─────────────────────────────┘1.2 渲染原理
Flutter 不使用原生控件,自己通过 Skia(现在是 Impeller)绘制 UI:
Widget 树(配置描述)
→ Element 树(生命周期管理)
→ RenderObject 树(布局和绘制)
→ Skia/Impeller → GPU → 屏幕- Widget:不可变的配置描述,类似 Compose 的 @Composable
- Element:Widget 的实例化,管理生命周期和状态,类似 Compose 的 Slot Table
- RenderObject:负责布局(layout)和绘制(draw),类似 Android 的 View
1.3 三棵树
Widget 树 Element 树 RenderObject 树
Container → ComponentElement → (无)
└─ Row → ComponentElement → RenderFlex
├─ Text → LeafElement → RenderParagraph
└─ Icon → LeafElement → RenderIconWidget 重建时,Element 通过 canUpdate(runtimeType + key 相同)判断是否复用,复用则更新 RenderObject,否则重建。
1.4 Platform Channel
Flutter 与 Native 通信的桥梁:
Flutter (Dart) ←→ Platform Channel ←→ Native (Kotlin/Swift)三种 Channel:
- MethodChannel:方法调用(一次性请求/响应)
- EventChannel:事件流(Native → Dart 的持续数据流,如传感器)
- BasicMessageChannel:自定义编解码的消息传递
dart
// Dart 端
final channel = MethodChannel('com.example/battery');
final batteryLevel = await channel.invokeMethod('getBatteryLevel');
// Kotlin 端
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/battery")
.setMethodCallHandler { call, result ->
if (call.method == "getBatteryLevel") {
result.success(getBatteryLevel())
} else {
result.notImplemented()
}
}1.5 混合开发
FlutterEngine:Dart VM 实例,创建开销大,建议预热缓存。
FlutterFragment / FlutterActivity:在原生 App 中嵌入 Flutter 页面。
页面栈管理:Flutter 和 Native 各有自己的页面栈,混合导航需要框架支持(如 flutter_boost)。
2. Kotlin Multiplatform (KMM)
2.1 架构
┌──────────────────────────────────┐
│ 共享模块 (commonMain) │ 业务逻辑、网络、数据库
├──────────┬───────────────────────┤
│ androidMain │ iosMain │ 平台特定实现
├──────────┼───────────────────────┤
│ Android App │ iOS App │ 原生 UI
└──────────┴───────────────────────┘2.2 expect / actual 机制
kotlin
// commonMain - 声明期望
expect class PlatformLogger() {
fun log(message: String)
}
// androidMain - Android 实现
actual class PlatformLogger {
actual fun log(message: String) {
Log.d("KMM", message)
}
}
// iosMain - iOS 实现
actual class PlatformLogger {
actual fun log(message: String) {
NSLog(message)
}
}2.3 共享范围
适合共享的:
- 网络层(Ktor)
- 数据库(SQLDelight)
- 业务逻辑
- 数据模型
- 序列化(kotlinx.serialization)
不适合共享的:
- UI(各平台原生 UI 体验更好)
- 平台特定 API(相机、蓝牙等)
2.4 与 Native 互操作
- Android:KMM 编译为 JVM 字节码,直接调用
- iOS:KMM 编译为 Kotlin/Native → LLVM → Framework,通过 Objective-C 互操作
3. React Native
3.1 新架构
旧架构:JS → Bridge(JSON 序列化)→ Native
新架构:JS → JSI(C++ 直接调用)→ Native- JSI(JavaScript Interface):JS 直接调用 C++ 对象,无需 JSON 序列化
- Fabric:新的渲染系统,支持同步渲染
- TurboModules:按需加载 Native 模块,替代旧的 NativeModules
3.2 与 Flutter 对比
| 维度 | Flutter | React Native |
|---|---|---|
| 语言 | Dart | JavaScript/TypeScript |
| 渲染 | 自绘(Skia/Impeller) | 原生控件 |
| 性能 | 接近原生 | 略低(JS 桥接开销) |
| UI 一致性 | 跨平台完全一致 | 跟随平台风格 |
| 生态 | 较新但增长快 | 成熟,npm 生态丰富 |
| 热更新 | 不支持(需要重新编译) | 支持(CodePush) |
4. 跨平台方案选型
| 维度 | Flutter | KMM | React Native |
|---|---|---|---|
| 共享范围 | UI + 逻辑 | 仅逻辑 | UI + 逻辑 |
| 原生体验 | 自绘,需要适配 | 原生 UI | 原生控件 |
| 学习成本 | Dart(新语言) | Kotlin(Android 开发者友好) | JS/TS |
| 适用场景 | 新项目、UI 一致性要求高 | 已有原生 App、共享业务逻辑 | 快速迭代、热更新需求 |
| 团队要求 | 需要 Flutter 开发者 | Android + iOS 开发者 | 前端开发者 |
选型建议:
- 已有成熟原生 App,想共享业务逻辑 → KMM
- 新项目,追求开发效率和 UI 一致性 → Flutter
- 团队以前端为主,需要热更新 → React Native
- 对性能要求极高的核心页面 → 保持原生
