<
现有的 android 项目中集成 flutter
>
上一篇

Android 后台任务 之 workmanager
下一篇

使用 ansi 转义序列,设置终端输出的文本颜色和样式(命令行窗口、ide 控制台等的文本输出)

现有的 Android 项目中集成 Flutter

集成 Flutter 模块

源码方式

  1. 创建 flutter module
flutter create -t module --org com.example module_flutter
  1. 执行 include flutter 脚本

module_flutter 的 .android/Flutter 是依赖的 Lib, 把 Lib 作为源码依赖使用 Lib 参考 .android 的 setting.gradle

module_flutter 的 .android/app 是可以独立运行的 app, 是使用 Lib 的形式

setBinding(new Binding([gradle: this]))

def flutterModulePath = rootDir.toString() + "/module_flutter"
def filePath = flutterModulePath + "/.android/include_flutter.groovy"

//apply from: filePath // 报错,参考 flutter module 的 `.android/settings.gradle` 用 evaluate
evaluate(new File(filePath)) // 执行 Flutter 作为 Lib 的脚本 include_flutter
  1. 依赖

集成时还需要修改 repositoriesMode

// settings.gradle
dependencyResolutionManagement {
//    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositoriesMode = RepositoriesMode.PREFER_SETTINGS
    // ...
}

添加 maven

// settings.gradle
dependencyResolutionManagement {
    // ...
    repositories {
        maven { url "https://storage.flutter-io.cn/download.flutter.io" }
        maven { url "https://storage.googleapis.com/download.flutter.io" }
    }
}

添加依赖

    implementation project(':flutter')
  1. 添加变体 profile

flutter 有三种模式:

android{
    buildTypes {
        debug {
            debuggable true
            minifyEnabled false
            shrinkResources false
            signingConfig signingConfigs.config
        }
        profile {
            initWith buildTypes.release
            matchingFallbacks = ['release']
            //
            debuggable false
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }
        release {
            debuggable false
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }
}
  1. 其它修改

flutter 支持的三种架构

android {
    // ...
    defaultConfig {
        ndk {
            // Filter for architectures supported by Flutter
            abiFilters "armeabi-v7a", "arm64-v8a", "x86_64"
        }
    }
}

aar 方式

dependencyResolutionManagement {
    repositories {
        maven(url = "https://storage.googleapis.com/download.flutter.io")
        maven(url = "module_flutter/build/host/outputs/repo")
    }
}
dependencies {
    // ...
    debugImplementation("com.example.module_flutter:flutter_debug:1.0")
    releaseImplementation("com.example.module_flutter:flutter_release:1.0")
    add("profileImplementation", "com.example.module_flutter:flutter_profile:1.0")
}

变体等参考上面的

使用 Flutter 的页面

// Activity 方式
val intent: Intent = FlutterActivity.createDefaultIntent(this)

// Fragment 方式
val flutterFragment: FlutterFragment = FlutterFragment.createDefault()

与 Flutter 通信

通过 平台通道(Platform Channels)在 Flutter 和 Android 原生代码之间传递数据。 Flutter 与 Android 之间可以通过消息通道来进行双向通信。

发送消息 Android –> Flutter

在 Android 中发送消息

val String CHANNEL = "com.example.myapp/channel"
MethodChannel(getFlutterEngine().getDartExecutor(), CHANNEL)
    .invokeMethod("sendData", "Hello from Android")

在 Flutter 中接收消息

class MyFlutterApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 定义 MethodChannel
    const platform = MethodChannel('com.example.myapp/channel');

    platform.setMethodCallHandler((MethodCall call) async {
      if (call.method == 'sendData') {
        print("Received data: ${call.arguments}");
      }
    });

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Flutter in Android')),
        body: Center(child: Text('Hello, Flutter!')),
      ),
    );
  }
}

发送消息 Flutter –> Android

在 Flutter 中发送消息(调用 Android 方法)

// 定义 MethodChannel
static const platform = MethodChannel('com.example.myapp/channel');

// 向 Android 发送消息并获取返回值
Future<void> _sendDataToAndroid() async {
  try {
    final String result = await platform.invokeMethod('getDataFromAndroid');
    print("Received data from Android: $result");
  } on PlatformException catch (e) {
    print("Failed to get data from Android: '${e.message}'.");
  }
}

在 Android 端接收 Flutter 消息并处理

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.myapp/channel"

    override fun configureFlutterEngine() {
        super.configureFlutterEngine()

        // 设置 MethodChannel
        MethodChannel(flutterEngine?.dartExecutor, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "sendData" -> {
                    // 从 Flutter 收到消息并处理
                    val data = call.arguments as String
                    println("Received from Flutter: $data")
                    result.success("Message received from Android: $data")
                }
                "getDataFromAndroid" -> {
                    // Flutter 请求从 Android 获取数据
                    val dataFromAndroid = "Data from Android"
                    result.success(dataFromAndroid)
                }
                else -> {
                    result.notImplemented()
                }
            }
        }
    }
}

git submodule 管理子模块

假设目前 git 管理了模块代码,切换到使用 git submodule 来管理

  1. 移除 module_flutter 的 Git 跟踪(此操作不会删除工作区文件)
git rm -r --cached module_flutter
  1. 进入 module_flutter 创建模块的 git 仓库,并提交远端仓库
cd module_flutter

git init
git add .
git commit -m "New Module"
git remote add origin ssh://admin@192.168.1.211:29418/module_flutter.git
git push -u origin master # 推送到远端
  1. 把目录文件移除(或移动到别的地方)

  2. 在目录不存在的前提下,在主仓库根目录执行添加 git submodule 的命令

git submodule add ssh://admin@192.168.1.211:29418/module_flutter.git module_flutter

会生成 .submodule 文件, git 会把子仓库 module_flutter 整个目录识别成文件,内容是子仓库的 HEAD 的 commitId

提交 .submodulemodule_flutter 到远端即可

后续初始化更新子模块

git submodule update --init

之后可以进入 submodule 使用 git 操作

  1. 到此基本完成 git submodule 的管理

可直接拉取远端最新代码

可选择恢复原来目录的文件(可以恢复 build 目录等忽略的文件), .git 文件和目录不要动,剪切移动除了 .git 外的文件恢复到原来目录

Top
Foot