阅读 222

(九)Android 项目集成 Flutter 模块

在实际项目开发中, 通常都是小的业务中尝试 Flutter ,所以都是使用 Flutter 写一个小界面,然后集成进已有的 Android 项目中

集成的方式主要有两种, 一种是通过 AndroidStudio 导入 Flutter Module 的方式, 一种是通过将 Flutter 工程打包成 AAR 然后放进 Android 项目中

通过 AndroidStudio 直接导入

在 AndroidStudio 重新建 Flutter 项目主要有4种类型:

  • Flutter Application

    用于构建面向用户的应用

  • Flutter Plugin

    导出 Android/iOS API 给开发者使用

  • Flutter Package

    用于创建纯 Dart 组件, 像 Widget 组件

  • Flutter Module

    用于创建 Flutter 组件, 集成进 Android/iOS 项目总

像使用 Flutter 写界面, 适合创建 Flutter Module

创建方式: File -> New -> New Flutter Project

创建完毕后, 在已经存在的 Android 项目上单击右键: New -> Module -> Import Flutter Module

import-flutter-module

然后就可以在 AndroidStudio 中看到导入的 Flutter 工程, 这个导入的 Flutter 工程实际上是我们刚刚新建的 Flutter Module 中的 .android 下的 Flutter 工程

我们来看下通过 AndroidStudio 的方式集成 Flutter 项目, 它到底为我们做了什么?

Android 项目中的 settings.gradle 文件中添加了如下配置, 主要是用于 include flutter

setBinding(new Binding([gradle: this]))
evaluate(new File(
  settingsDir.parentFile,
  '..\\Flutter\\flutter_module\\.android\\include_flutter.groovy'
))

复制代码

Android 工程的 app 目录下的 build.gradle 文件中添加了:

implementation project(':flutter')
复制代码

最终在 AndroidStudio 中展示如下图所示:

androidStudio-flutter

然后可以尝试 build 下工程, 可能会出现 Manifest Merge Failed 的错误

主要原因可能是已有的Android工程中使用的是 support 包, 而在 Flutter 工程中使用的是 androidx

所以需要统一, 由于 supportGoogle 今后不会再维护了, 改用 androidx 了, 所以大家最好将 Android 项目中的 support 包改成 androidx

GoogleAndroidStudio 中为我们提供了一键替换的功能:

对Android项目单击右键 -> Refactor -> Migrate to Androidx

除此以外还需要兼容 Java 8 , 在 app/build.gradle 添加如下配置:

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

最后我们可以测试下, 将 Flutter 中的某个页面集成进 Android 项目中的主页面中


private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                if (firstFragment == null) {
                    firstFragment = createFragment("first");
                }
                showFragment(firstFragment, "first");
                hideFragment(secondFragment);
                hideFragment(thirdFragment);
                return true;
            case R.id.navigation_dashboard:
                if (secondFragment == null) {
                    secondFragment = createFragment("second");
                }
                showFragment(secondFragment, "second");
                hideFragment(firstFragment);
                hideFragment(thirdFragment);
                return true;
                
            // from flutter page
            case R.id.navigation_notifications:
                if (thirdFragment == null) {
                    thirdFragment = Flutter.createFragment(null);
                }
                showFragment(thirdFragment, "flutter");
                hideFragment(firstFragment);
                hideFragment(secondFragment);
                return true;
        }
        return false;
    }
};
复制代码

效果如下图所示:

在这里插入图片描述

通过 AAR 的方式引入

除了上面的通过引入 Flutter Module.android/Flutter 工程外, 可以把该工程打包成 aar 文件

然后 Android 项目依赖 aar 文件即可, 这样可以其他开发者不用安装 Flutter 环境也可以编译运行已有 Android 的项目

既然上面的例子已经将 .android/Flutter 引入到了 Android 项目中, 并且可以成功运行, 说明主要的依赖配置是没有问题的, 加上相关的配置就可以生成 aar 文件了

我将需要的配置单独放在了 maven.gradle 文件中, 减少对已有 gradle 的侵入

maven.gradle 文件内容为:

apply plugin: 'maven'
apply plugin: 'com.kezong.fat-aar'

dependencies {
    def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
    def plugins = new Properties()
    def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
    if (pluginsFile.exists()) {
        pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
    }
    plugins.each { name, _ ->
        println name
        embed project(path: ":$name", configuration: 'default')
    }
}

def mavenRepositoryUrl = 'file:\\D:\\repo'

uploadArchives {
    repositories.mavenDeployer {
        repository(url: mavenRepositoryUrl) {
            //authentication(userName: xxx, password: xxx)
        }
        pom.groupId = 'com.chiclaim.flutter'
        pom.artifactId = 'flutter-module'
        pom.version = '1.0.0'
    }
}

task androidSourcesJar2Nexus(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.sourceFiles
}
artifacts {
    archives androidSourcesJar2Nexus
}
repositories {
    mavenCentral()
}

复制代码

Flutter 模块还可能使用第三方插件, 还需要使用 com.kezong:fat-aar

所以还需要在 .android/Flutter/build.gradle 文件中加上如下配置

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.kezong:fat-aar:1.1.7'
    }
}

// 最后引入 maven.gradle 文件
apply from: 'maven.gradle'
复制代码

如果读者需要使用上面的配置, 记得将 mavenRepositoryUrl 改成自己本地的目录, 也可以将上面的配置改成上传至 NEXUS 服务器上

然后双击 uploadArchives, 如下图所示:

flutter-aar-upload

会在 mavenRepositoryUrl 所指定的目录生成 aar 文件, 如下图所示:

flutter-aar-dir

最后将生成的 aar 文件拷贝到 Android 中, 运行效果如下图所示:

android-flutter-aar

可以看出第三个 Tab 的内容没有 DEBUG 标志, 说明我们刚刚打出来的 aar 文件是 release 的, 并且当我们切换到第三个 tab 的时候界面的显式速度也很快, 比上面的例子要快一些. 通过 AndroidStudio 直接导入我们是导入了源代码, 运行 Android 项目的时候是 debug 方式运行的, 所以对应的 .android/Flutter 也是 debug

小结

本文介绍了 Android 项目集成 Flutter 模块的两种方式

总的来说每种方式都有它的缺点和优点, 在实际项目中可以根据情况灵活使用

  • 通过 AndroidStudio 直接导入

    这种方式缺点是需要每个开发成员都需要安装 Flutter 开发环境. 好处是当我们编写一些插件的时候和原生进行交互的时候可以直接运行调试, 而不用将其打包成 aar 文件, 然后替换原来的 aar 文件, 替换 aar 文件后, Android 需要重新 load 一下

  • 通过 AAR 的方式引入

    这种方式缺点上面也说了, 调试的时候需要频繁将其打包成 AAR, 然后替换老的 AAR 文件. 优点是项目其他成员不需要安装 Flutter 环境

本文涉及到的案例可以在我的 github.com/chiclaim/An…

到此就介绍完了 Android 项目集成 Flutter 模块, 如果有什么问题欢迎留言交流.

公众号:  chiclaim

关注下面的标签,发现更多相似文章
评论