在移动开发中,将 Flutter 集成到现有的原生 Android 或 iOS 项目中是一种常见的混合开发模式(Add-to-App)。这种方式允许开发者在保留现有原生业务的同时,利用 Flutter 高效构建新的 UI 模块。
本文将详细介绍如何创建一个 Flutter Module,将其打包为库文件,并在原生 Android 和 iOS 项目中进行集成。
1. 创建 Flutter Module
首先,我们需要创建一个 Flutter Module 项目,而不是标准的 Flutter App。Module 项目专门用于嵌入到宿主应用中。
在终端中运行以下命令:
flutter create -t module my_flutter_module
这将创建一个名为 my_flutter_module 的目录。该项目的结构与普通 Flutter 项目略有不同,它包含 .android 和 .ios 隐藏目录,用于辅助构建。
2. Android 项目打包与集成
Android 平台通常使用 AAR (Android Archive) 包的方式进行集成。
2.1 打包 AAR
进入 Flutter Module 根目录,执行构建命令:
cd my_flutter_module
flutter build aar
构建成功后,终端会输出具体的集成指引,通常包含以下信息:
- AAR 产物的路径(通常在
build/host/outputs/repo)。 - 需要在宿主 Android 项目中添加的 Gradle 配置。
2.2 宿主项目配置 (Android)
打开你的原生 Android 项目,修改 build.gradle 文件。
第一步:添加本地仓库路径
在项目级 build.gradle (Project level) 或 settings.gradle 中,将 Flutter 构建的本地仓库添加到 repositories 块中:
Groovy
// settings.gradle 或 build.gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// 添加这一行,路径指向 Flutter Module 的 repo 目录
maven { url 'path/to/my_flutter_module/build/host/outputs/repo' }
}
}
第二步:添加依赖
在应用级 build.gradle (App level, 通常是 app/build.gradle) 中添加依赖:
Groovy
dependencies {
// 添加 debug 模式依赖
debugImplementation 'com.example.my_flutter_module:flutter_debug:1.0'
// 添加 profile 模式依赖 (用于性能分析)
profileImplementation 'com.example.my_flutter_module:flutter_profile:1.0'
// 添加 release 模式依赖
releaseImplementation 'com.example.my_flutter_module:flutter_release:1.0'
}
注:具体的 groupId(com.example.my_flutter_module) 可以在 Flutter Module 的 pubspec.yaml中配置,或者查看 flutter build aar的输出日志。
2.3 Android 代码接入
为了提升启动速度,建议在 Application 启动时预热 FlutterEngine。
在 Application 类中初始化:
java
// MyApplication.java
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
public class MyApplication extends Application {
public FlutterEngine flutterEngine;
@Override
public void onCreate() {
super.onCreate();
// 1. 实例化 FlutterEngine
flutterEngine = new FlutterEngine(this);
// 2. 配置初始路由(可选)并执行 Dart 代码
flutterEngine.getNavigationChannel().setInitialRoute("/");
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
);
// 3. 将 FlutterEngine 存入缓存,使用 ID "my_engine_id"
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
}
}
启动 Flutter 页面:
java
// 在 Activity 或 Fragment 中启动
import io.flutter.embedding.android.FlutterActivity;
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(currentActivity)
);
3. iOS 项目打包与集成
iOS 平台通常将 Flutter 打包为 XCFramework 或 Framework 进行集成。
3.1 打包 Framework
在 Flutter Module 根目录下运行:
bash
flutter build ios-framework --output=./flutter_frameworks
该命令会在 flutter_frameworks 目录下生成三种构建模式的产物:
Debug/:包含调试功能的 Framework,体积较大,用于开发。Profile/:用于性能分析。Release/:用于正式发布。
每个目录下通常包含:
App.xcframework:包含你的 Dart 代码和资源。Flutter.xcframework:Flutter 引擎。- 以及其他依赖插件的 Framework。
3.2 宿主项目配置 (iOS)
- 打开 Xcode 项目。
- 根据当前的构建配置(Debug 或 Release),将对应的
App.xcframework和Flutter.xcframework(以及其他插件 Framework) 拖入到工程导航栏中。 - 选中你的 Target,进入 General -> Frameworks, Libraries, and Embedded Content。
- 确保导入的 Frameworks 的 Embed 选项被设置为 Embed & Sign。
注意:在实际开发中,为了方便切换 Debug/Release,通常会使用 CocoaPods 脚本来动态引入不同模式的 Framework,或者在 Build Phases 中添加脚本处理。
3.3 iOS 代码接入
同样建议在 AppDelegate 中预热引擎。
在 AppDelegate 中初始化:
Swift
// AppDelegate.swift
import UIKit
import Flutter
import FlutterPluginRegistrant // 如果使用了插件
@UIApplicationMain
class AppDelegate: FlutterAppDelegate { // 继承自 FlutterAppDelegate
lazy var flutterEngine = FlutterEngine(name: "my_engine_id")
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 1. 运行 Flutter 引擎
flutterEngine.run();
// 2. 注册插件(如果需要)
GeneratedPluginRegistrant.register(with: flutterEngine);
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
}
启动 Flutter 页面:
Swift
// 在 ViewController 中
import Flutter
func showFlutter() {
// 获取 AppDelegate 中的引擎
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
// 创建 FlutterViewController
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
// 跳转
self.present(flutterViewController, animated: true, completion: nil)
}
4. 总结
通过 Flutter Module,我们可以灵活地将 Flutter 页面嵌入到现有的原生应用中。
- Android :核心是通过
flutter build aar生成本地 Maven 仓库,利用 Gradle 依赖管理进行集成。 - iOS :核心是通过
flutter build ios-framework生成 Framework 产物,通过手动嵌入或 CocoaPods 集成。 - 性能优化 :无论哪种平台,使用
FlutterEngineCache预热引擎都是提升首屏打开速度的关键步骤。