Flutter 混合开发指南:项目打包与原生 Android/iOS 集成

在移动开发中,将 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

构建成功后,终端会输出具体的集成指引,通常包含以下信息:

  1. AAR 产物的路径(通常在 build/host/outputs/repo)。
  2. 需要在宿主 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 打包为 XCFrameworkFramework 进行集成。

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)

  1. 打开 Xcode 项目。
  2. 根据当前的构建配置(Debug 或 Release),将对应的 App.xcframeworkFlutter.xcframework (以及其他插件 Framework) 拖入到工程导航栏中。
  3. 选中你的 Target,进入 General -> Frameworks, Libraries, and Embedded Content
  4. 确保导入的 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 预热引擎都是提升首屏打开速度的关键步骤。
相关推荐
卡尔特斯2 小时前
Windows Flutter fvm 多版本管理安装与常用指令(详细使用)
flutter
如此风景2 小时前
iOS SwiftUI 布局容器详解
ios
2501_915921432 小时前
从需求到上架,现代 iOS 开发流程的工程化方法论
android·ios·小程序·https·uni-app·iphone·webview
weixin_447671993 小时前
【MySQL从节点异常断连后的Slave_SQL_Running 处于Connecting的解决方案】
android·sql·mysql
笨小孩7873 小时前
Flutter全解析:从入门到实战的跨平台开发指南
flutter
豫狮恒3 小时前
OpenHarmony Flutter 分布式软总线实战:跨设备通信的核心技术与应用
flutter·wpf·harmonyos
_大学牲3 小时前
全网爆火的豆包手机,到底是如何实现自动化的?一篇文章带你了解
android·人工智能·agent
L、2183 小时前
Flutter 与 OpenHarmony 跨端融合新范式:基于 FFI 的高性能通信实战
flutter·华为·智能手机·electron·harmonyos
lin62534224 小时前
Android仿小米视频播放器的缩放滚轮
android·git·github