Skip to content

跨平台方案 — 知识详解

更新: 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       →  RenderIcon

Widget 重建时,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 对比

维度FlutterReact Native
语言DartJavaScript/TypeScript
渲染自绘(Skia/Impeller)原生控件
性能接近原生略低(JS 桥接开销)
UI 一致性跨平台完全一致跟随平台风格
生态较新但增长快成熟,npm 生态丰富
热更新不支持(需要重新编译)支持(CodePush)

4. 跨平台方案选型

维度FlutterKMMReact Native
共享范围UI + 逻辑仅逻辑UI + 逻辑
原生体验自绘,需要适配原生 UI原生控件
学习成本Dart(新语言)Kotlin(Android 开发者友好)JS/TS
适用场景新项目、UI 一致性要求高已有原生 App、共享业务逻辑快速迭代、热更新需求
团队要求需要 Flutter 开发者Android + iOS 开发者前端开发者

选型建议:

  • 已有成熟原生 App,想共享业务逻辑 → KMM
  • 新项目,追求开发效率和 UI 一致性 → Flutter
  • 团队以前端为主,需要热更新 → React Native
  • 对性能要求极高的核心页面 → 保持原生