前言
Flutter作为新一代移动端跨平台解决方案,相比于React Native等有很大的性能优势,所以很多公司已经开始研究Flutter并将其应用于实际项目中,目前包括闲鱼、美团、京东和今日头条等都已经在APP部分页面尝试使用了,那么它们这些应用都已经使用原生开发的很成熟了且代码量非常大,如果全面使用Flutter改造势必是一个浩大的工程,所以他们都使用Flutter混合开发的模式渐进式的对部分页面进行改造。
接下来几篇文章我们将分析若干种混合开发方案来为大家在现有APP中引入Flutter做参考。本篇我们将先介绍Flutter官方提供的混合开发集成方案。
官方集成方案
官方提供的集成步骤详见:
https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps
根据官方集成方案将Flutter集成到现有APP工程中会有一些小问题在,后边集成的过程中会提到。以下集成步骤我们假定现有安卓和iOS的APP工程分别为flutter_host_android和flutter_host_ios,两个工程放在同一目录下,如下
some/path/
flutter_host_android/
flutter_host_ios/
注意:
以下工程的创建基于Flutter channel为 stable 1.2.1版本
创建Flutter工程
根据官方说明,我们需要创建一个Flutter module工程(是module而不是app),命令行定位到以上some/path/
目录下,使用如下命令创建
flutter create --org=com.flutterbus.app --type=module flutter_module
创建完成后flutter_module工程和安卓、iOS的APP工程在同一目录中,结构如下
some/path/
flutter_host_android/
flutter_host_ios/
flutter_module/
使用Android Studio打开flutter_module项目,目录结构如下
从目录结构中我们可以看出Flutter module项目中的安卓和iOS工程和Flutter app项目中的不同,他们都是隐藏的工程,其实官方是不建议在这两个原生工程中添加任何平台代码的,这两个工程用于对Flutter项目进行测试。
根据模板生成的main.dart中的代码不是图中这样的,我们稍微做了一些修改,仅供参考,这里的defaultRouteName是由平台原生层传入的routeName,我们可以根据不同的routeName展示不同的页面Widget。这里面的代码修改后边再做说明,下面我们看一下具体的集成步骤。
安卓集成
Flutter工程下的aar产物构建
在将flutter_module项目集成到安卓原生工程flutter_host_android之前,需要先将flutter_module项目中的安卓工程构建出一个aar,命令行切换到flutter_module目录下,执行以下命令
cd .android
./gradlew assembleDebug
执行完成后.android/Flutter/build/output/aar/
目录下就会有一个flutter-debug.aar产物生成。
原生工程配置
修改原生工程flutter_host_android下的app module中的build.gradle,在android{}
配置中添加一下内容
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
必须添加,否则在执行’:app:mergeExtDexDebug’任务时会报如下错误
org.gradle.api.UncheckedIOException: Failed to capture fingerprint of input files for task ':app:mergeExtDexDebug' property 'dexFiles' during up-to-date check.
at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository.fingerprintTaskFiles(CacheBackedTaskHistoryRepository.java:360)
...
Caused by: com.android.builder.dexing.DexArchiveBuilderException: Error while dexing.
The dependency contains Java 8 bytecode. Please enable desugaring by adding the following to build.gradle
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
See https://