Android 项目集成 Flutter

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。

相信大家在 最开始学习 Flutter 时都是使用命令行或者 Android Studio 等集成开发环境创建的 Flutter 项目,自动生成的 Flutter 项目模板包含了 Flutter 代码、Android 代码、iOS代码,直接运行就行。

但是公司的项目都是分开管理的,例如 Android、iOS是两个独立的项目在 git 中管理,与 Flutter 的模板项目还是存在差别的。

Android 现有项目集成 Flutter 方案

在现有 Android 项目中集成 Flutter 官方给出两种方案。

  1. 将 Flutter 打包成 AAR 包,然后在现有项目引入。
  2. 将 Flutter 源码视为 Gradle Module 引入现有项目。

1. 将 Flutter 打包成 AAR 包,然后在现有项目引入

使用 AAR 形式集成 Flutter 可以不用安装 Flutter SDK。可以将 AAR 上传到Maven 或 jcenter 仓库(jcenter 即将停止服务,所以还是使用 maven 吧)。这样应用起来更方便。如果代码更新比较频繁使用 AAR 形式集成则需要经常构建、发布,所以大家根据自己的项目及使用场景自行选择集成方案。

如何生成 AAR 包

生成 AAR 包通常有两种方式。

1. 使用 flutter 命令

假设构建一个 Flutter 模块 some/path/my_flutter,然后运行:

$ cd some/path/my_flutter
$ flutter build aar
复制代码

build-aar-instructions-59deccd46ba2e0b0552f4dfe7e195406395d24aa6ac03eb8ff4ec2c1ca182fd9.png

至此 flutter 命令会在本地创建一个 maven 仓库,其目录结构如下:

build/host/outputs/repo
└── com
    └── example
        └── my_flutter
            ├── flutter_release
            │   ├── 1.0
            │   │   ├── flutter_release-1.0.aar
            │   │   ├── flutter_release-1.0.aar.md5
            │   │   ├── flutter_release-1.0.aar.sha1
            │   │   ├── flutter_release-1.0.pom
            │   │   ├── flutter_release-1.0.pom.md5
            │   │   └── flutter_release-1.0.pom.sha1
            │   ├── maven-metadata.xml
            │   ├── maven-metadata.xml.md5
            │   └── maven-metadata.xml.sha1
            ├── flutter_profile
            │   ├── ...
            └── flutter_debug
                └── ...
复制代码

如果要引用本地仓库中的 aar 包则需要在宿主应用的 build.gradle 中做如下配置即可:

android {
  // ...
}

repositories {
  maven {
    url 'some/path/my_flutter/build/host/outputs/repo'
    // This is relative to the location of the build.gradle file
    // if using a relative path.
  }
  maven {
    url 'https://storage.googleapis.com/download.flutter.io'
  }
}

dependencies {
  // ...
  debugImplementation 'com.example.flutter_module:flutter_debug:1.0'
  profileImplementation 'com.example.flutter_module:flutter_profile:1.0'
  releaseImplementation 'com.example.flutter_module:flutter_release:1.0'
}
复制代码

2. 使用 Android Studio

第二种生成 AAR 包的方式就是使用 Android Studio,这用方式比较简单,依次选择 AS > Build > Flutter > Build AAR 然后等着就行了。剩下的步骤和使用 flutter 命令一样。

image.png

2. 将 Flutter 源码视为 Gradle Module 引入现有项目。

这种方式是推荐的方式,因为在团队协作过程中这种方式更方便,相对于 AAR 方式可以省掉每次单独构建 AAR 包的步骤。可以一键构建 Android、Flutter 代码。

使用此种集成方式可以按照如下步骤进行。

1. 组织目录结构

因为绝大多数的现有 Android、iOS 项目都是作为独立项目使用 svn 或 git 进行版本管理的(这里以 git 为例)。在不改变原有项目管理方式的前提下集成 Flutter 需要将 Flutter 的代码作为独立的工程使用 git 进行管理,并在 Android 项目中以 module 的形式进行依赖。其目录结构如下。

workspace
├── android_project
└── flutter_module
复制代码

android_project是我们现有的 Android 工程代码目录。flutter_module是我们新增的 fluuter 模块代码目录,将两个工程放到同一目录下。为了统一配置,建议必须按照这个目录结构进行管理两个工程的代码。

注意:flutter_module是 module,不是 project 类型,在 Android Studio 中一定要选择 File > New > New Module > Flutter Module,不要选择File > New > New Flutter Project

创建 flutter module 也可以使用如下命令:

$ flutter create -t module name_of_module
复制代码

2. 配置 settings.gradle

在 Android 工程的 settings.gradle做如下修改

// Include the host app project.
include ':app'                                    // assumed existing content
setBinding(new Binding([gradle: this]))                                // new
evaluate(new File(                                                     // new
  settingsDir.parentFile,                                              // new
  'my_flutter/.android/include_flutter.groovy'                         // new
))                                                                     // new
复制代码

3. 依赖 flutter 模块

在 Android 模块的 build.gradle中加入如下依赖。

dependencies {
  implementation project(':flutter')
}
复制代码

然后单击Sync Now同步 Gradle 即可。

完成这一步就可以在 Android 原生代码中使用 flutter 模块了。

4. 配置 AndroidManifest.xml

启动 flutter 模块需要使用FlutterActivity,所以需要在 AndroidManifest.xml 中注册一下。

<activity
  android:name="io.flutter.embedding.android.FlutterActivity"
  android:theme="@style/LaunchTheme"
  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"/>
复制代码

5. 启动 Flutter 模块

在任意地方执行如下代码即可启动 Flutter 模块。

startActivity(FlutterActivity
                .withNewEngine()
                .initialRoute("splashRoute") // 启动指定 Flutter page,没有可以省略
                .build(requireContext()))
复制代码

注意事项

1. abiFilters 配置

因为 Flutter 目前仅支持x86_64、armeabi-v7a和arm64-v8a架构. 所以为了避免运行时崩溃建议在 build.gradle中做如下配置。

android {
  //...
  defaultConfig {
    ndk {
      // Filter for architectures supported by Flutter.
      abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
    }
  }
}
复制代码

2. Java 8 要求

因为Flutter Android 引擎需要使用 Java 8。所以需要在宿主 Android 工程的 build.gradle中做如下配置。

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}
复制代码

3. storage.googleapis.com 国内访问不了?

  1. “学会科学上网”
  2. 使用国内镜像

4. Android 模块改过名字?

Android Studio 默认创建的模块名称是app。在 settings.gradle中有如下配置。

include ':app'
复制代码

只有在这里 include 的模块才能通过 gradle 进行构建。

模块的名字是可以修改的,如果你改过 app 模块的名字,则在集成 flutter 时会报错。

java.lang.AssertionError: Project :app doesn't exist. To custom the host app project name, set org.gradle.project.flutter.hostAppProjectName=<project-name> in gradle.properties.. Expression: (appProject != null). Values: appProject = null

因为 flutter 默认会认为名为“app”的模块依赖自己,如果你修改过名字则会报错,此时只需要根据报错信息提示在宿主工程的gradle.properties中加入如下配置即可。

flutter.hostAppProjectName = your_module_name
复制代码

your_module_name修改成你真是的模块名称即可。

5. flutter module 不支持自定义 buildType?

如果 app module 的 buildType 中除了releasedebug之外有自定义的 variant那么在打包的时候可能会报错,因为在 flutter module 并没有你定义的 variant 类型,但是releasedebug这两种 variant 是所有 module 都包含的。所以可以在 app module 的 buildType 中的自定义 buildType 中增加如下配置。

matchingFallbacks = ['debug', 'release']
复制代码

例如:

   buildTypes {
        release {...}

        debug {...}

        beta {
            ...
            matchingFallbacks = ['debug', 'release']
        }
    }
复制代码

参考

Integrate a Flutter module into your Android project

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享