Android集成Flutter模块经验记录
记录Android原生项目集成Flutter模块经验,其中不乏一些踩坑,也是几番查找资料之后才成功运用于实际开发。
主要为了记录,将使用简洁的描述。
Flutter开发环境
1. Flutter安装和环境配置
官方文档:https://flutter.cn/docs/get-started/install
参照官方文档一步步按步骤即可
下载SDK->解压->配置PATH环境变量
其中配置PATH环境变量务必使其永久生效方式
2. AS安装flutter和dart插件
AS安装flutter和dart插件将 Flutter module 集成到 Android 项目
官方文档:https://flutter.cn/docs/add-to-app/android/project-setup?tab=with-android-studio#add-the-flutter-module-as-a-dependency
仍然主要是参照官方文档。
有分为使用AS集成和不使用AS集成,其中使用AS集成有AAR集成和使用模块源码集成两种方式。
- AAR 集成: AAR 机制可以为每个 Flutter 模块创建 Android AAR 作为依赖媒介。当你的宿主应用程序开发者不想安装 Flutter SDK 时,这是一个很好方案。但是每次修改都需要重新编译。
- 模块源码集成:直接将 Flutter 模块的源码作为子项目的依赖机制是一种便捷的一键式构建方案,但此时需要另外安装 Flutter SDK,这是目前 Android Studio IDE 插件使用的机制。
本文讲述的是使用模块源码集成的方式。
1.创建Flutter Module
使用File > New > New Flutter Project创建,选择Module,官方建议Flutter Module和Android项目在同一个目录下。
2. 配置Module
在Android项目的 settings.gradle中添加以下配置:flutter_module为创建的flutter module名称
// Include the host app project.
include ':app' // assumed existing content
setBinding(new Binding([gradle: this])) // new
evaluate(new File( // new
settingsDir.parentFile, // new
'flutter_module/.android/include_flutter.groovy' // new
)) // new
在应用中引入对 Flutter 模块的依赖:
dependencies {
implementation project(':flutter')
}
3. 编译失败报错:Failed to apply plugin class 'FlutterPlugin'
gradle6.8后 在settings.gradle的dependencyResolutionManagement 下新增了如下配置:
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
RepositoriesMode配置在构建中仓库如何设置,总共有三种方式:
FAIL_ON_PROJECT_REPOS
表示如果工程单独设置了仓库,或工程的插件设置了仓库,构建就直接报错抛出异常
PREFER_PROJECT
表示如果工程单独设置了仓库,就优先使用工程配置的,忽略settings里面的
PREFER_SETTINGS
表述任何通过工程单独设置或插件设置的仓库,都会被忽略
settings.gradle里配置的是FAIL_ON_PROJECT_REPOS,Flutter插件又单独设置了repository,所以会构建报错,因此需要把FAIL_ON_PROJECT_REPOS改成PREFER_PROJECT。
因为gradle调整,Android仓库配置都在settings.gradle中,但是因为设置了PREFER_PROJECT,settings.gradle被忽略了,那该怎么解决呢?发现虽然project的gradle文件虽然调整了,但是依然可以跟之前一样配置仓库这些,于是在项目build.gradle中加上settings.gradle中的所有仓库,成功解决问题并编译安装成功。
allprojects{
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
maven { url "https://s01.oss.sonatype.org/content/groups/public" }
maven { url 'https://jitpack.io' }
google()
// 极光 fcm, 若不集成 FCM 通道,可直接跳过
maven { url "https://maven.google.com" }
maven {
url 'https://artifact.bytedance.com/repository/pangle'
}
}
}
总结:需要先将settings.gradle中repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)替换为repositoriesMode.set(RepositoriesMode.PREFER_PROJECT),
然后在项目build.gradle中添加settings.gradle中的所有仓库。
添加Flutter页面
官方文档:https://flutter.cn/docs/add-to-app/android/add-flutter-screen
Flutter 提供了 FlutterActivity,用于在 Android 应用内部展示一个 Flutter 的交互界面。需要在清单文件中注册FlutterActivity。
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:screenOrientation="portrait"
/>
然后加载FlutterActivity
startActivity(
FlutterActivity.createDefaultIntent(requireContext())
)
此外还有withNewEngine、withCachedEngine等多种加载方式,具体可见官方文档。
添加Flutter视图
官方文档:https://flutter.cn/docs/add-to-app/android/add-flutter-view
参考官方demo:https://github.com/flutter/samples/tree/main/add_to_app/android_view
创建FlutterViewEngine用以管理FlutterView、FlutterEngine、Activity三者。
FlutterEngine用以执行dart执行器,"showCell"为dart中方法名,FlutterEngine和FlutterView attach之后,会将"showCell"中生成的ui绘制到FlutterView上。
val engine = FlutterEngine(BaseApplication.instance)
engine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint(
FlutterInjector.instance().flutterLoader().findAppBundlePath(),
"showCell"))
在原生页面里面添加FlutterView还是比较麻烦的,需要开发者自己管理FlutterView、FlutterEngine、Activity三者之间生命周期联系。