一、前言

2020 年 flutter 不再是什么新的技术,以‘闲鱼’为首各大 app 纷纷拥抱 flutter,目前最理想的就是完全用 flutter 开发,但是由于各自的 app 都以成型,完全抛弃以前的代码全面上 flutter ,无论是人力还是物力都是不切实际的,所以目前大多数产品的思路都是进行混合开发,逐步 flutter 化

由于各大 app 牵入 flutter 较早,使用技术过于老旧,鉴于这一点,我结合 Google 最新的官方文档和网上的总结,研究出一套切实可行的方案,供大家参考

二、准备

  • 既然是混合开发,首先需要两个工程:一个 Android 工程, 一个 flutter工程
2.1 打开 android 工程
  • Android studio 直接 new 或者打开现有的就行,没有特殊要求

2.2 新建 flutter 工程

  • flutter 工程这里有两种情况:
  • flutter 工程已存在,直接导入使用
  • 纯新项目,直接以 module 新式新建即可
2.2.1 已存在 flutter 工程
  • 直接打开就行
  • 进入到 Terminal(mac 系统是:同时按下 command + shirft + p 打开)
2.2.2 需要新建 flutter 项目
  • 如果你还没有 flutter 项目,需要新建则选择 Android studio 进行:
  • 打开 Android studio 在 file 里选 new - new module
  • 输入名字新建即可,没有什么特殊的配置
  • 新建完可以 sync 一下

三、接入

  • 接入继承上面所讲,分接入已存在 flutter 工程和接入 module
  • 在这之前我们先要对 Android 项目进行配置

3.1 Android 项目公共配置

  • 步骤如下
3.1.1 配置 ndk
android {
  //...
  defaultConfig {
    ndk {
      // Filter for architectures supported by Flutter.
      abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
    }
  }
}
  • 位置如下
3.1.2 配置 Java 8
  • 在 build.gradle 配置 Java 8,新版默认已经配置
android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}
  • 配置路径如下:

3.2 接入 Flutter Module

  • 老样子 flutter 工程这里有两种情况:
  • 已有的 flutter 工程
  • 刚刚以 module 形式新建的 flutter 工程
  • 这里先讲刚刚以 module 形式新建的 flutter 工程的接入方法
3.2.1 Android Flutter Module 接入
  • 通过 Terminal cd 到 module 下直接打 arr
  • 根据提示对 build.gradle 进行修改
1. Open <host>/app/build.gradle
  2. Ensure you have the repositories configured, otherwise add them:

      repositories {
        maven {
            url '/Users/huangyuanhao/StudioProjects/flutter_module/build/host/outputs/repo'
        }
        maven {
            url 'http://download.flutter.io'
        }
      }

  3. Make the host app depend on the Flutter module:

    dependencies {
      debugImplementation 'com.superpentagon.fluttermodule:flutter_debug:1.0
      profileImplementation 'com.superpentagon.fluttermodule:flutter_profile:1.0
      releaseImplementation 'com.superpentagon.fluttermodule:flutter_release:1.0
    }


  4. Add the `profile` build type:

    android {
      buildTypes {
        profile {
          initWith debug
        }
      }
    }
  • 修改后如下:
  • ⚠️ 注意:有些内容需要修改
  • 获得 repo 路径并替换,替换成你自己机子的的 repo 路径
  • 替换国内镜像,这里我用的是清华的镜像,如果失效的话请到这里进行选择:flutter 社区镜像获取
maven {
        url 'https://mirrors.tuna.tsinghua.edu.cn/flutter/download.flutter.io'
    }
  • 修改如下
  • 最后在这里替换成你本地的包名哈
3.2.2 测试运行
  • 在 MainActivity 里调用 Flutter ,部分工具代码详见:Super-Pentagon - p01_android_proj
// 初始化 Flutter
        FlutterMain.Settings settings=new FlutterMain.Settings();
        settings.setLogTag("MyFlutter");
        FlutterMain.startInitialization(this,settings);
        String[] args = {"info", "data"};
        FlutterMain.ensureInitializationComplete(this,args);

        // 初始化 FlutterEngine.
        FlutterEngine flutterEngine = new FlutterEngine(this);
        // Configure an initial route.
        flutterEngine.getNavigationChannel().setInitialRoute(FlutterEngineUtils.Home.HOME_PAGE_ROUTE + "?{\"message\":\"StephenCurry\"}");
        // Start executing Dart code to pre-warm the FlutterEngine.
        flutterEngine.getDartExecutor().executeDartEntrypoint(
                DartExecutor.DartEntrypoint.createDefault()
        );
        // Cache the FlutterEngine to be used by FlutterActivity or FlutterFragment.
        FlutterEngineCache
                .getInstance()
                .put(FlutterEngineUtils.Home.HOME_PAGE_ROUTE, flutterEngine);


        FlutterOperationUtil.init().initFragmentById(FlutterEngineUtils.Home.HOME_PAGE_ROUTE).initLayoutId(R.id.main_container).startFlutterTransation(getSupportFragmentManager());
  • 布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <FrameLayout
            android:id="@+id/main_container"
            android:visibility="visible"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </RelativeLayout>

</LinearLayout>
  • 详见如下:
  • 由于设计代码太多,一些工具类详见:Super-Pentagon - p01_android_proj
3.2.3 perfectly 测试运行
  • 完美运行

四、总结

  • 看到这里有些读者肯定会遇到一个问题:有些项目可能很早就已经介入了 Flutter 所以这里就难用再用 Module 方式接入
  • 这是解决方就是打包 arr 其实打包的方法也非常简单,但限于篇幅原因这里就不做展开了
  • 下一篇文章中我将进行详细的介绍