原生Android和Flutter集成主要有两种方案:

1.源码集成:官方提供的源码集成方案 2.产物集成:Flutter 项目单独开发,开发完成后发布成 aar 包或者 iOS 的 framework 形式,原生项目依赖 Flutter 输出的文件即可。
3.咸鱼团队的FlutterBoost 方案。FlutterBoost地址

环境

首先确认环境是否正确:
这里重点关注一下Flutter version的版本。在后面介绍集成开发的时候,不同的Flutter版本有差别。

flutter doctor -v

下面是我的环境信息:

flutter 和android混合项目 混淆 flutter混合开发android_android

集成

创建Android项目

略过新建 Native Android项目的流程。

注意点:
(1)现在创建的Flutter module默认是支持Android X的,所以如果想在现有的项目中集成Flutter module需要把support包替换成Android x。所有这里是通过新建一个 Native Android项目(默认支持Android x)来演示混合开发流程。
(2)配置信息,需要在app/build.gradle里设置

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}

创建Flutter module

  1. 切换 flutter 的 channel 到 master (master 分支下是 flutter 的 preview 版本)
flutter channel master
  1. 创建 flutter module项目
    module后面是新建的Flutter module的名称。
flutter create -t module flutter_test
  1. Flutter module的目录结构:
    (1)在 flutter 的模块项目中包含有一个隐藏的 .android 和 .ios 目录这个目录下是可运行的 Android 和 iOS 项目。
    (2)flutter代码写在 lib下,注意在 .android 和 .ios 目录下都有一个 Flutter 目录,这个是我们 flutter 的库项目了。也就是Android 用来生成 aar,iOS 用来生产 framework 的库。
    (3 Flutter Application项目是没有.android 和.ios目录的。Flutter Application项目下对应的是android和ios这两个目录。
  2. git管理Flutter module
    (1)把项目使用 git 管理起来,后面会在 native 项目中以submodule的形式引入native项目。
    略过git上传到远程git仓库的过程。
    (2)重点关注一下gitignore文件的编辑
    编辑一下项目下的 .gitignore 文件,需要把项目下的 .ios 和 .android 忽略掉。
    这里有个坑,有的文章说要把.packages也忽略掉,但是根据我的实验是不行的,建议大家还是把.packages通过git管理起来。
    (3)我的gitignore配置信息
.DS_Store
.dart_tool/
.pub/
.idea/
.vagrant/
.sconsign.dblite
.svn/
*.swp
profile
DerivedData/
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
build/
.ios/Flutter/Generated.xconfig
.flutter-plugins

Native Android 项目集成 Flutter

  1. native android 项目集成 Flutter
    (1)将目录切换到native android代码目录下
    (2)将Flutter module添加到native android中。
git submodule add flutter module的仓库地址
git submodule update
  1. 在native android根目录的 settings.gradle中添加如下配置
    这里的路径使用的是相对于native android 项目的路径。
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir,
        'flutter_test/.android/include_flutter.groovy'
))
  1. 在native android项目的 app 目录下的 build.gradle 文件中添加 Flutter 库的依赖
implementation project(':flutter')
  1. 从新rebuild项目以后,在native android项目目录下会多一个flutter module子项目。

代码编写

通过native怎么加载flutter widget呢?Flutter提供了以下集中方法。(Flutter不同版本存在差异)
6.1 通过FlutterFragment类
直接在对应的native activity 布局文件中添加FlutterFragment即可。

<fragment
            android:id="@+id/flutterfragment"
            android:name="io.flutter.embedding.android.FlutterFragment"
            android:layout_width="300dp"
            android:layout_height="500dp" />

6.2 通过FlutterActivity类
在 AndroidManifest.xml 中注册

<activity
                android:name="io.flutter.embedding.android.FlutterActivity"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
                android:exported="true"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize" />

默认启动方式:默认路由为 ‘/’

import io.flutter.embedding.android.FlutterActivity
val intent = FlutterActivity.createDefaultIntent(this)
startActivity(intent)

启动到指定路由

val customFlutter = FlutterActivity.withNewEngine()
            .initialRoute("newRoute")
            .build(this)
        startActivity(customFlutter)

6.3 通过FlutterView类
通过该类没有实现效果,待研究

FlutterView flutterView = new FlutterView(this);
        FrameLayout frameLayout = findViewById(R.id.framelayout);
        frameLayout.addView(flutterView);
       //创建一个 FlutterView 就可以了,这个时候还不会渲染。
      //调用下面代码后才会渲染
        flutterView.attachToFlutterEngine(new FlutterEngine(this));

集成中经历的坑

  1. finished with non-zero exit value 1
Process 'command '/Users/mtdp/Documents/Flutter/flutter/bin/flutter'' finished with non-zero exit value 1

造成这个的原因是缺少.packages文件,所有在通过git管理flutter module的时候,尽量把.packages保留。
2. 废弃类
Flutter默认在某个版本以后已经不支持facade了。
Flutter version 1.7.8+hotfix.4版本还是支持的,具体从那个版本移除了,还不清楚。

io.flutter.facade.*

ps:以前的方式(deprecated) ( io.flutter.facade )
通过使用 Flutter.createView:

View flutterView = Flutter.createView(
      MainActivity.this,
      getLifecycle(),
      "route1"
    );
    FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
    layout.leftMargin = 100;
    layout.topMargin = 200;
    addContentView(flutterView, layout);

通过使用 Flutter.createFragment:

FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
    tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
    tx.commit();

git submodule删除后重新添加问题

  1. 重新添加git 子模块出现的问题:
A git directory for 'formRenderLib' is found locally with remote(s):
  origin   xxxxxx
If you want to reuse this local git directory instead of cloning again from
  xxxx
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

说明没有删除干净之前的module
2. 解决方法:
2.1 在native android主项目目录下,删除指定模块的文件

git rm --cached module名称

2.2 打开主项目目录下 .gitmodules 删除和submodule相关的配置信息
2.3 打开主项目目录下 .git/config 文件删除和submodule相关的配置信息
2.4 删除.git下的缓存模块

rm -rf .git/modules/submodule名称

2.5 添加子模块

git submodule add submodule的git仓库