1.8. 平台集成与发布

Flutter 通过平台通道与原生代码交互,并提供完善的打包发布能力。

1.8.1. 平台通道(Platform Channel)

Flutter 与原生代码之间通过 MethodChannel 通信:

Flutter (Dart)          Native (Kotlin/Swift)
┌────────────┐         ┌──────────────────┐
│ 调用方法    │ ──────→ │ 处理并返回结果    │
│ await       │ ←────── │                   │
│ result      │         │                   │
└────────────┘         └──────────────────┘
       MethodChannel

1.8.1.1. Dart 端(Flutter)

import 'package:flutter/services.dart';

class BatteryPlugin {
  static const _channel = MethodChannel('com.example/battery');

  static Future<int> getBatteryLevel() async {
    try {
      final level = await _channel.invokeMethod('getBatteryLevel');
      return level as int;
    } on PlatformException catch (e) {
      print('获取电量失败: ${e.message}');
      return -1;
    }
  }
}

1.8.1.2. Android 端(Kotlin)

// MainActivity.kt
class MainActivity : FlutterActivity() {
  private val CHANNEL = "com.example/battery"

  override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
      .setMethodCallHandler { call, result ->
        if (call.method == "getBatteryLevel") {
          val batteryLevel = getBatteryLevel()
          if (batteryLevel != -1) {
            result.success(batteryLevel)
          } else {
            result.error("UNAVAILABLE", "无法获取电量", null)
          }
        } else {
          result.notImplemented()
        }
      }
  }

  private fun getBatteryLevel(): Int {
    val intent = registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
    val level = intent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1
    val scale = intent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1
    return if (level > 0 && scale > 0) (level * 100 / scale) else -1
  }
}

1.8.1.3. iOS 端(Swift)

// AppDelegate.swift
import Flutter
import UIKit

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller = window?.rootViewController as! FlutterViewController
    let channel = FlutterMethodChannel(
      name: "com.example/battery",
      binaryMessenger: controller.binaryMessenger
    )
    channel.setMethodCallHandler { (call, result) in
      if call.method == "getBatteryLevel" {
        let device = UIDevice.current
        device.isBatteryMonitoringEnabled = true
        let level = Int(device.batteryLevel * 100)
        if level >= 0 {
          result(level)
        } else {
          result(FlutterError(code: "UNAVAILABLE", message: "无法获取电量", details: nil))
        }
      } else {
        result(FlutterMethodNotImplemented)
      }
    }
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

小技巧

使用 Pigeon 可以自动生成类型安全的平台通道代码,避免手动编写样板代码。

1.8.2. 常用插件(packages)

插件

用途

状态

url_launcher

打开 URL、拨打电话、发送邮件

官方

image_picker

从相册/相机获取图片/视频

官方

permission_handler

权限管理(相机、位置、通知等)

社区

local_auth

生物识别认证(指纹、Face ID)

官方

camera

相机预览与拍照

官方

geolocator

GPS 定位

社区

flutter_local_notifications

本地通知

社区

firebase_core

Firebase 核心(需配合其他 Firebase 插件)

官方

share_plus

系统分享面板

社区

file_picker

文件选择器

社区

备注

使用插件前请查阅其 pub.dev 页面的 Platforms 标签, 确认它支持你的目标平台。

1.8.3. 应用打包与发布

1.8.3.1. Android 发布

# 1. 生成签名密钥
keytool -genkey -v -keystore release.jks \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias release

# 2. 创建 key.properties
# 在 android/ 目录下创建 key.properties:
#   storePassword=xxx
#   keyPassword=xxx
#   keyAlias=release
#   storeFile=release.jks

# 3. 构建 APK / AAB
flutter build apk                # APK
flutter build appbundle          # AAB(推荐上传 Google Play)

# 产物路径:
# build/app/outputs/flutter-apk/app-release.apk
# build/app/outputs/bundle/release/app-release.aab

1.8.3.2. iOS 发布

# 1. 在 Xcode 中配置证书和签名
open ios/Runner.xcworkspace

# 2. 构建 IPA
flutter build ios

# 3. 通过 Xcode Archive 发布
# Product → Archive → Distribute App

1.8.3.3. Web 发布

flutter build web
# 产物在 build/web/ 目录

# 部署到任意静态文件服务器
# 或 Firebase Hosting
firebase deploy --only hosting

1.8.3.4. Windows / macOS / Linux 发布

flutter build windows    # Windows 安装包
flutter build macos      # macOS .app(需 Mac)
flutter build linux      # Linux 应用

重要

发布前务必: - 更新版本号(pubspec.yaml 中的 version 字段) - 检查应用图标和启动页 - 清理调试日志和打印语句 - 测试不同设备和屏幕尺寸

1.8.4. CI/CD 与测试

1.8.4.1. 测试类型

// 单元测试
void main() {
  test('Counter 初始值应为 0', () {
    final counter = Counter();
    expect(counter.value, 0);
  });
}

// Widget 测试
testWidgets('Counter 按钮应增加计数值', (tester) async {
  await tester.pumpWidget(const MyApp());
  await tester.tap(find.byIcon(Icons.add));
  await tester.pump();
  expect(find.text('1'), findsOneWidget);
});

1.8.4.2. CI/CD 配置

.github/workflows/flutter.yml
name: Flutter CI
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.x'
      - run: flutter pub get
      - run: flutter analyze
      - run: flutter test
      - run: flutter build apk

1.8.5. 贴士与最佳实践

  • 优先使用 Flutter 内置 API,仅在必要时编写平台通道代码

  • 使用 Pigeon 自动生成安全的平台通道接口

  • 插件筛选:优先选择官方插件(flutter.dev 维护),确认 pub.dev 评分和维护状态

  • 及时更新:保持 Flutter SDK 和依赖的最新稳定版本

  • 测试覆盖:至少为关键业务逻辑编写单元测试

  • 性能分析:使用 flutter devtools 进行性能分析和内存泄漏排查