欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > Flutter 学习之旅 之 flutter 作为 module ,在 Android 的界面中嵌入Flutter界面功能的简单整理

Flutter 学习之旅 之 flutter 作为 module ,在 Android 的界面中嵌入Flutter界面功能的简单整理

2025/4/29 19:33:45 来源:https://blog.csdn.net/u014361280/article/details/147586609  浏览:    关键词:Flutter 学习之旅 之 flutter 作为 module ,在 Android 的界面中嵌入Flutter界面功能的简单整理

Flutter 学习之旅 之 flutter 作为 module ,在 Android 的界面中嵌入Flutter界面功能的简单整理

目录

Flutter 学习之旅 之 flutter 作为 module ,在 Android 的界面中嵌入Flutter界面功能的简单整理

一、简单介绍

二、在同一个布局中同时显示 Android 和 Flutter 界面 的实现原理

1. Flutter 的嵌入机制

2. FlutterEngine 的作用

3. FlutterView 的工作原理

4. FlutterFragment 的工作原理

三、简单效果预览

四、案例简单实现步骤

五、关键代码


一、简单介绍

Flutter 是一款开源的 UI 软件开发工具包,由 Google 开发和维护。它允许开发者使用一套代码同时构建跨平台的应用程序,包括移动设备(iOS 和 Android)、Web 和桌面平台(Windows、macOS 和 Linux)。

Flutter 使用 Dart 编程语言,它可以将代码编译为 ARM 或 Intel 机器代码以及 JavaScript,从而实现快速的性能。Flutter 提供了一个丰富的预置小部件库,开发者可以根据自己的需求灵活地控制每个像素,从而创建自定义的、适应性强的设计,这些设计在任何屏幕上都能呈现出色的外观和感觉。

二、在同一个布局中同时显示 Android 和 Flutter 界面 的实现原理

在同一个布局中同时显示 Android 和 Flutter 界面的实现原理主要基于 Flutter 提供的嵌入机制,允许 Flutter 内容以视图的形式嵌入到原生 Android 布局中。以下是其实现原理的详细解释:

1. Flutter 的嵌入机制

Flutter 提供了两种主要方式将 Flutter 内容嵌入到原生 Android 应用中:

  • FlutterView:这是一个原生的 Android 视图,用于显示 Flutter 内容。

  • FlutterFragment:这是一个 Android Fragment,用于将 Flutter 内容嵌入到 Android 的 Fragment 管理系统中。

这两种方式的核心是通过 FlutterEngine 来运行 Flutter 的 Dart 代码,并将渲染结果绘制到一个原生的 Android 视图中。

2. FlutterEngine 的作用

FlutterEngine 是 Flutter 提供的一个核心组件,用于初始化和运行 Flutter 的 Dart 代码。它负责以下任务:

  • 加载 Dart 代码:从 APK 或其他资源中加载 Dart 文件,并执行 Dart 入口点(通常是 main() 函数)。

  • 管理渲染线程:负责将 Flutter 的渲染内容绘制到原生视图中。

  • 处理平台通道通信:通过 MethodChannelEventChannel 实现 Flutter 和原生代码之间的通信。

  • 管理生命周期:与 Android 的生命周期(如 onPauseonResume)同步,确保 Flutter 内容在合适的时机进行渲染和暂停。

3. FlutterView 的工作原理

FlutterView 是一个原生的 Android 视图,用于显示 Flutter 内容。它的实现原理如下:

  • 创建 FlutterEngine:在 Android 代码中创建一个 FlutterEngine 实例,并将其与 FlutterView 关联。

  • 绑定 Dart 代码:通过 FlutterEngine 加载 Dart 代码,并指定 Dart 的入口点(通常是 main() 函数)。

  • 渲染 Flutter 内容FlutterView 会接收来自 Flutter 引擎的渲染指令,并将其绘制到视图中。Flutter 引擎会将渲染内容转换为 OpenGL 或 Skia 的绘图命令,并通过 FlutterViewSurfaceTextureView 进行渲染。

4. FlutterFragment 的工作原理

FlutterFragment 是一个 Android Fragment,用于将 Flutter 内容嵌入到 Android 的 Fragment 管理系统中。它的实现原理如下:

  • 创建 FlutterEngine:与 FlutterView 类似,FlutterFragment 也需要一个 FlutterEngine 实例来运行 Dart 代码。

  • 生命周期管理FlutterFragment 会根据 Android 的 Fragment 生命周期(如 onCreateonResume)管理 Flutter 引擎的生命周期,确保 Flutter 内容在合适的时机进行初始化和销毁。

  • 视图嵌入FlutterFragment 内部会创建一个 FlutterView,并将 Flutter 内容渲染到该视图中。通过 Fragment 的 onCreateView 方法,将 FlutterView 返回给 Android 系统,从而实现 Flutter 内容的嵌入。

三、简单效果预览

四、案例简单实现步骤

1、在 Android Studio 中创建一个 Flutter 工程

2、选择创建 一个 Flutter Module

3、编写一个简单的 Flutter 界面

4、先再创建一个 Android 工程

5、回到 Flutter 工程,进行 Flutter - Build AAR 编译

6、编译完成后, 会有提示如何在 Android 工程中引用

7、在 Android 工程中,根据提示,在 settings.gradle 和 build.gradle 添加如下的提示内容

8、在 activity_main.xml 中添加一个 按钮,用来调起 Flutter 界面

9、在 MainActivity 中 引入 Flutter 相关,并实现点击 按钮 唤起 Flutter 界面的代码

10、在 AndroidManifest.xml 中,添加 FlutterActivity 相关属性

11、打包运行,简单效果如下

五、关键代码

1、main.dart

import 'package:flutter/material.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo', // 设置应用的标题,显示在系统任务栏或窗口标题中theme: ThemeData(primarySwatch: Colors.blue, // 设置应用的主题颜色,这里使用蓝色作为主色调),home: MyHomePage(), // 设置应用的初始页面为 MyHomePage);}
}class MyHomePage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold( // 使用 Scaffold 提供一个基本的页面布局结构appBar: AppBar( // 添加一个应用栏(AppBar)作为页面的顶部导航title: Text('Flutter Module in Android'), // 设置应用栏的标题),body: Center( // 设置页面的主体内容child: Text('Hello from Flutter!'), // 在页面中心显示一条文本消息),);}
}

2、MainActivity.java

package com.example.test_android_embedding_flutter_0428;import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;import io.flutter.embedding.android.FlutterFragment;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;public class MainActivity extends AppCompatActivity {private FlutterEngine flutterEngine; // 用于运行 Flutter Dart 代码的核心引擎@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); // 设置当前 Activity 的布局文件// 初始化 FlutterEngine// 创建一个 FlutterEngine 实例,用于运行 Flutter 的 Dart 代码flutterEngine = new FlutterEngine(this);// 执行 Dart 入口点,默认是 main() 函数flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());// 将 FlutterEngine 实例缓存到 FlutterEngineCache 中// 这样可以在需要时快速复用,避免重复初始化FlutterEngineCache.getInstance().put("my_flutter_engine", flutterEngine);// 获取按钮并设置点击事件findViewById(R.id.button).setOnClickListener(v -> {// 创建 FlutterFragment 实例// FlutterFragment 是一个 Android Fragment,用于嵌入 Flutter 界面FlutterFragment flutterFragment = FlutterFragment.createDefault();// 开始一个 Fragment 事务FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();// 将 FlutterFragment 替换到布局中的 FrameLayout 容器中// R.id.fl_container 是布局文件中定义的 FrameLayout 的 IDtransaction.replace(R.id.fl_container, flutterFragment);// 提交事务,使 Flutter 界面显示出来transaction.commit();});}
}

代码注释说明

  1. FlutterEngine 的初始化

    • new FlutterEngine(this):创建一个 FlutterEngine 实例,用于运行 Flutter 的 Dart 代码。

    • executeDartEntrypoint:指定 Dart 的入口点,默认是 main() 函数。这是 Flutter 应用的起点。

    • FlutterEngineCache.getInstance().put("my_flutter_engine", flutterEngine):将初始化好的 FlutterEngine 缓存起来,以便后续复用。这可以避免重复初始化 Flutter 引擎,提高性能。

  2. 按钮点击事件

    • findViewById(R.id.button):通过 ID 获取布局中的按钮。

    • setOnClickListener:为按钮设置点击事件监听器。

    • FlutterFragment.createDefault():创建一个默认的 FlutterFragment 实例。FlutterFragment 是一个 Android Fragment,用于嵌入 Flutter 界面。

    • getSupportFragmentManager().beginTransaction():开始一个 Fragment 事务,用于管理 Fragment 的添加、替换等操作。

    • transaction.replace(R.id.fl_container, flutterFragment):将 FlutterFragment 替换到布局中的 FrameLayout 容器中。R.id.fl_container 是布局文件中定义的容器 ID。

    • transaction.commit():提交事务,使 Flutter 界面显示出来。

3、activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- 定义一个按钮,点击后会显示 Flutter 界面 --><Buttonandroid:id="@+id/button"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="打开 Flutter 界面" /><!-- 定义一个 FrameLayout 作为容器,用于嵌入 Flutter 界面 --><FrameLayoutandroid:id="@+id/fl_container"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />
</LinearLayout>

4、AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Test_Android_Embedding_Flutter_0428"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:windowSoftInputMode="adjustResize"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

5、settings.gradle

pluginManagement {// 配置插件管理相关的设置repositories {// 定义插件管理的仓库来源google {// 使用 Google 的 Maven 仓库content {// 定义需要包含的组(group)正则表达式includeGroupByRegex("com\\.android.*")  // 包含以 "com.android" 开头的组includeGroupByRegex("com\\.google.*")   // 包含以 "com.google" 开头的组includeGroupByRegex("androidx.*")       // 包含以 "androidx" 开头的组}}mavenCentral()  // 使用 Maven Central 仓库gradlePluginPortal()  // 使用 Gradle 插件门户}
}dependencyResolutionManagement {// 配置依赖解析相关的设置repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)  // 设置仓库模式,如果项目中有仓库配置错误则失败repositories {google()  // 使用 Google 的 Maven 仓库mavenCentral()  // 使用 Maven Central 仓库}// 定义 Flutter 模块的存储 URLString storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"// 如果环境变量 FLUTTER_STORAGE_BASE_URL 未设置,则使用默认的 Flutter 存储 URL// 注意:该 URL 是 Flutter 依赖项的默认存储位置,但由于网络原因,可能无法直接访问// 如果您遇到问题,请检查链接的合法性或在网络正常的情况下重试repositories {maven {// 定义本地 Maven 仓库路径url 'D:/UsingForXAN/Projects/AndroidStudioProjects/FlutterProject/test_flutter_module_0418/build/host/outputs/repo'}maven {// 定义远程 Maven 仓库路径url "$storageUrl/download.flutter.io"}}
}// 设置项目的根项目名称
rootProject.name = "Test_Android_Embedding_Flutter_0428"
// 包含子项目 'app',这是 Android 项目的主模块
include ':app'

6、build.gradle

plugins {alias(libs.plugins.android.application)
}
// 定义项目使用的插件
// 这里使用了 alias 来引用预定义的插件,通常是定义在 buildSrc 或其他地方的插件别名
// 这里引用的是 Android 应用插件,用于构建 Android 应用android {namespace 'com.example.test_android_embedding_flutter_0428'// 设置项目的命名空间,用于区分不同的应用compileSdk 35// 设置编译 SDK 的版本,这里是 API 级别 35defaultConfig {applicationId "com.example.test_android_embedding_flutter_0428"// 设置应用的唯一标识符minSdk 28// 设置应用支持的最低 SDK 版本targetSdk 34// 设置应用的目标 SDK 版本versionCode 1// 设置应用的版本代码,用于内部版本管理versionName "1.0"// 设置应用的版本名称,显示给用户testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"// 设置用于运行 Android 测试的测试运行器}buildTypes {release {minifyEnabled false// 是否启用代码混淆,这里设置为 false 表示不启用proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'// 指定 ProGuard 配置文件,用于代码混淆规则}profile {initWith debug// 将 profile 构建类型初始化为 debug 构建类型的配置}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8// 设置源代码的 Java 版本兼容性targetCompatibility JavaVersion.VERSION_1_8// 设置目标字节码的 Java 版本兼容性}
}dependencies {// 定义项目的依赖项implementation libs.appcompat// 添加 AndroidX AppCompat 库的依赖,用于支持旧版本 Android 的兼容性implementation libs.material// 添加 Material Design 组件库的依赖,用于构建 Material Design 风格的界面implementation libs.activity// 添加 Activity 组件库的依赖,用于支持新的 Activity APIimplementation libs.constraintlayout// 添加 ConstraintLayout 布局库的依赖,用于构建复杂的布局testImplementation libs.junit// 添加 JUnit 测试框架的依赖,用于编写单元测试androidTestImplementation libs.ext.junit// 添加扩展的 JUnit 测试框架的依赖,用于 Android 测试androidTestImplementation libs.espresso.core// 添加 Espresso 测试框架的依赖,用于编写 UI 测试debugImplementation 'com.example.test_flutter_module_0418:flutter_debug:1.0'// 在 debug 构建类型中添加 Flutter 模块的 debug 版本依赖profileImplementation 'com.example.test_flutter_module_0418:flutter_profile:1.0'// 在 profile 构建类型中添加 Flutter 模块的 profile 版本依赖releaseImplementation 'com.example.test_flutter_module_0418:flutter_release:1.0'// 在 release 构建类型中添加 Flutter 模块的 release 版本依赖
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词