flutter-android混合编译,原生接入

news/2025/2/3 7:25:57/

关于作者: CSDN内容合伙人、技术专家, 从零开始做日活千万级APP,带领团队单日营收超千万。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业化变现、人工智能等,希望大家多多支持。

目录

  • 一、导读
  • 二、概览
  • 三、以原生module依赖
  • 四、以aar方式依赖一
  • 五、以aar方式依赖二
  • 六、 推荐阅读

在这里插入图片描述

一、导读

我们继续总结学习flutter基础知识,温故知新。

二、概览

本文主要讲解原生Android工程接入Flutter ,进行混合编程。

首先,需要开发者按照原生Android、iOS的搭建流程搭建好开发环境。
然后,去Flutter官网下载最新的SDK,下载完毕后解压到自定义目录即可。

下载完后,还需要配置好环境,具体可参考 上一篇的 flutter配置的文章。

我们讲解一下三种方式;

Flutter 可以作为源代码 Gradle 子项目或 AAR 嵌入到现有的 Android 应用程序中。

集成流程可以使用带有Flutter 插件的Android Studio IDE或手动完成。

现有的 Android 应用可能支持mips或 等架构x86。Flutter 目前仅支持x86_64为、armeabi-v7a和构建预先 (AOT) 编译库arm64-v8a。

考虑使用abiFiltersAndroid Gradle 插件 API 来限制 APK 中支持的架构。这样做可以避免缺失libflutter.so运行时崩溃,例如:

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

三、以原生module依赖

创建flutter module,然后以原生module那样依赖

自行参考
参考文档
参考文档

四、以aar方式依赖一

另一种方式是将flutter module打包成aar,然后在原生工程中依赖aar包,官方推荐aar的方式接入。

参考文档
参考文档

创建一个flutter module,然后打包成aar,这个过程就省略一下。
在 /flutter_module/.android/Flutter/build/outputs 目录下生成对应的aar包。

stuff@ddddeMacBook-Pro loktar % flutter build aarRunning Gradle task 'assembleAarDebug'...                           7.1s
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarProfile'...                      1,714ms
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarRelease'...                      1,642ms
✓ Built build/host/outputs/repoConsuming the Module1. Open <host>/app/build.gradle2. Ensure you have the repositories configured, otherwise add them:String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"repositories {maven {// 本地仓库,也是创建的 flutter工程目录, 也可以是自己创建的一个目录,然后把编译后的产物拷贝过来url '/Users/stuff/dddd/working/flutter_pro/loktar/build/host/outputs/repo'}maven {url "$storageUrl/download.flutter.io"}}3. Make the host app depend on the Flutter module:dependencies {debugImplementation 'com.ddd:flutter_debug:1.0'profileImplementation 'com.ddd:flutter_profile:1.0'releaseImplementation 'com.ddd:flutter_release:1.0'}4. Add the `profile` build type:android {buildTypes {profile {initWith debug}}}To learn more, visit https://flutter.dev/go/build-aar

接下来,就是在原生Android工程中集成aar即可。

第一,在build.gradle中添加如下配置。

android {...buildTypes {profile {initWith debug}} String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?:"https://storage.googleapis.com"repositories {maven {// 本地仓库,也即是创建的 flutter工程目录url '/Users/mac/Flutter/module_flutter/build/host/outputs/repo'}maven {url "$storageUrl/download.flutter.io"}}
}repositories {flatDir {dirs 'libs'}
}
dependencies {debugImplementation 'com.ddd.module_flutter:flutter_debug:1.0'profileImplementation 'com.ddd.module_flutter:flutter_profile:1.0'releaseImplementation 'com.ddd.module_flutter:flutter_release:1.0'}

第二、在AndroidManifest.xml中注册FlutterActivity实现

<activityandroid:name="io.flutter.embedding.android.FlutterActivity"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:theme="@style/AppTheme"android:windowSoftInputMode="adjustResize" /><meta-dataandroid:name="flutterEmbedding"android:value="2" />

第三、启动FlutterActivity

context.startActivity(FlutterActivity.withNewEngine().build(context));// 
Intent intent = FlutterActivity.withCachedEngine(FlutterHelper.FLUTTER_ENGINE).build(context);
//重新设置一下目标class到子类BridgeActivity.class
intent.setClass(context, FlutterActivity.class);
context.startActivity(intent);

五、以aar方式依赖二

flutter module打包成aar,然后在原生工程中依赖aar包, 但这种方式跟前一种有少许区别。

在新建的flutter工程中,可以看一下.android 目录下Flutter/build.gradle文件。

apply plugin: "com.android.library"
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
想来,这就是flutter 相关的依赖,
我们在进入到目录下看看其他的gradle文件,发现有个依赖相关的文件,后面用到。

创建一个flutter module,然后打包成aar,这个过程就省略一下。
在 /flutter_module/.android/Flutter/build/outputs 目录下生成对应的aar包。

stuff@ddddeMacBook-Pro loktar % flutter build aarRunning Gradle task 'assembleAarDebug'...                           7.1s
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarProfile'...                      1,714ms
✓ Built build/host/outputs/repo
Running Gradle task 'assembleAarRelease'...                      1,642ms
✓ Built build/host/outputs/repoConsuming the Module1. Open <host>/app/build.gradle2. Ensure you have the repositories configured, otherwise add them:String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"repositories {maven {url '/Users/stuff/dddd/working/flutter_pro/loktar/build/host/outputs/repo'}maven {url "$storageUrl/download.flutter.io"}}3. Make the host app depend on the Flutter module:dependencies {debugImplementation 'com.ddd:flutter_debug:1.0'profileImplementation 'com.ddd:flutter_profile:1.0'releaseImplementation 'com.ddd:flutter_release:1.0'}4. Add the `profile` build type:android {buildTypes {profile {initWith debug}}}To learn more, visit https://flutter.dev/go/build-aar

接下来,就是在原生Android工程中集成aar即可。

第一,在app的目录下新建libs文件夹,然后将生成aar包放入libs文件夹中

第二、新建一个flutter依赖文件
首先,在local.properties 目录新增flutter目录

sdk.dir=/Users/sd/Library/Android/sdk
flutter.sdk=/Users/sd/development/flutter

然后在 “$flutter sdk目录/packages/flutter_tools/gradle/” 中找到resolve_dependencies.gradle文件,复制到app目录下。
然后进行修改如下:

// This script is used to warm the Gradle cache by downloading the Flutter dependencies
// used during the build. This script is invoked when `flutter precache` is run.
//
// Command:
//  gradle -b <flutter-sdk>packages/flutter_tools/gradle/resolve_dependencies.gradle
//      resolveDependencies
//
// This way, Gradle can run with the `--offline` flag later on to eliminate any
// network request during the build process.
//
// This includes:
//   1. The embedding
//   2. libflutter.soimport java.nio.file.Paths///add
//获取local.properties配置文件
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')if (localPropertiesFile.exists()) {localPropertiesFile.withReader('UTF-8') {reader -> localProperties.load(reader)}
}//获取flutter的sdk路径
def flutterRootPath = localProperties.getProperty('flutter.sdk')if (flutterRootPath == null) {throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
} endString storageUrl = System.getenv('FLUTTER_STORAGE_BASE_URL') ?: "https://storage.googleapis.com"//File flutterRoot = projectDir.parentFile.parentFile.parentFile
File flutterRoot = new File(flutterRootPath)String engineRealm = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.realm").toFile().text.trim()
if (engineRealm) {engineRealm = engineRealm + "/"
}repositories {google()mavenCentral()maven {url "$storageUrl/${engineRealm}download.flutter.io"}
}assert flutterRoot.isDirectory()
String engineVersion = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.version").toFile().text.trim()System.out.println("hrl Resolving dependencies for Flutter $engineVersion")configurations {flutterRelease.extendsFrom releaseImplementationflutterDebug.extendsFrom debugImplementationflutterProfile.extendsFrom debugImplementation
}dependencies {flutterRelease "io.flutter:flutter_embedding_release:1.0.0-$engineVersion"flutterRelease "io.flutter:armeabi_v7a_release:1.0.0-$engineVersion"flutterRelease "io.flutter:arm64_v8a_release:1.0.0-$engineVersion"flutterProfile "io.flutter:flutter_embedding_profile:1.0.0-$engineVersion"flutterProfile "io.flutter:armeabi_v7a_profile:1.0.0-$engineVersion"flutterProfile "io.flutter:arm64_v8a_profile:1.0.0-$engineVersion"flutterDebug "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"flutterDebug "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"flutterDebug "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"flutterDebug "io.flutter:x86_debug:1.0.0-$engineVersion"flutterDebug "io.flutter:x86_64_debug:1.0.0-$engineVersion"//    compileOnly "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:x86_debug:1.0.0-$engineVersion"
//    compileOnly "io.flutter:x86_64_debug:1.0.0-$engineVersion"debugImplementation "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"debugImplementation "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"debugImplementation "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"debugImplementation "io.flutter:x86_debug:1.0.0-$engineVersion"debugImplementation "io.flutter:x86_64_debug:1.0.0-$engineVersion"releaseImplementation "io.flutter:flutter_embedding_release:1.0.0-$engineVersion"releaseImplementation "io.flutter:armeabi_v7a_release:1.0.0-$engineVersion"releaseImplementation "io.flutter:arm64_v8a_release:1.0.0-$engineVersion"
}

第三、在build.gradle中添加如下配置。


allprojects {repositories {maven {url "https://storage.googleapis.com/download.flutter.io"}}
}

然后在app的build.gradle中添加如下配置。

apply from: "${rootDir}/resolve_dependencies.gradle"repositories {flatDir {dirs 'libs'}
}dependencies {implementation fileTree(include: ['*.jar'], dir: 'libs')releaseImplementation(name:'flutter_release-1.0', ext:'aar')debugImplementation(name:'flutter_debug-1.0', ext:'aar')
}

第四、在AndroidManifest.xml中注册FlutterActivity实现

<activityandroid:name="io.flutter.embedding.android.FlutterActivity"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"android:hardwareAccelerated="true"android:theme="@style/AppTheme"android:windowSoftInputMode="adjustResize" />
<meta-dataandroid:name="flutterEmbedding"android:value="2" />

第五、启动FlutterActivity

context.startActivity(FlutterActivity.withNewEngine().build(context));// 
Intent intent = FlutterActivity.withCachedEngine(FlutterHelper.FLUTTER_ENGINE).build(context);
//重新设置一下目标class到子类BridgeActivity.class
intent.setClass(context, FlutterActivity.class);
context.startActivity(intent);

如此即可

六、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

未经允许,不得转载。

ddd


http://www.ppmy.cn/news/1568898.html

相关文章

JVM的GC详解

获取GC日志方式大抵有两种 第一种就是设定JVM参数在程序启动时查看&#xff0c;具体的命令参数为: -XX:PrintGCDetails # 打印GC日志 -XX:PrintGCTimeStamps # 打印每一次触发GC时发生的时间第二种则是在服务器上监控:使用jstat查看,如下所示&#xff0c;命令格式为jstat -gc…

【deepseek实战】绿色好用,不断网

前言 最佳deepseek火热网络&#xff0c;我也开发一款windows的电脑端&#xff0c;接入了deepseek&#xff0c;基本是复刻了网页端&#xff0c;还加入一些特色功能。 助力国内AI&#xff0c;发出自己的热量 说一下开发过程和内容的使用吧。 目录 一、介绍 二、具体工作 1.1、引…

流浪 Linux: 外置 USB SSD 安装 ArchLinux

注: ArchLinux 系统为滚动更新, 变化很快, 所以本文中的安装方法可能很快就过时了, 仅供参考. 实际安装时建议去阅读官方文档. 最近, 突然 (也没有那么突然) 有了一大堆 PC: 4 个笔记本, 2 个台式主机 (M-ATX 主板), 1 个小主机 (迷你主机). 嗯, 多到用不过来. 但是, 窝又不能…

K8s之Service详解(Detailed Explanation of K8s Service)

K8s之Service详解 1 Service相关概念 1.1 什么是Service&#xff1f; 在 Kubernetes 中&#xff0c;Service 是一种抽象的资源&#xff0c;它提供了稳定的访问接口&#xff0c;将外部或集群内部的流量路由到对应的 Pod 上。Pod 是 Kubernetes 中的基本调度单元&#xff0c;…

C#@符号在string.Format方法中作用

本文详解@符号在string.Format方法中作用。

解决运行npm时报错

在运行一个Vue项目时报错&#xff0c;产生下面问题 D:\node\npm.cmd run dev npm WARN logfile could not be created: Error: EPERM: operation not permitted, open D:\node\node_cache\_logs\2025-01-31T01_01_58_076Z-debug-0.log npm WARN logfile could not be created:…

ELECTRA:作为判别器而非生成器的预训练文本编码器

摘要 诸如BERT之类的掩码语言建模&#xff08;MLM&#xff09;预训练方法通过将某些标记替换为[MASK]来破坏输入&#xff0c;然后训练模型以重建原始标记。尽管这些方法在下游自然语言处理&#xff08;NLP&#xff09;任务中表现良好&#xff0c;但它们通常需要大量的计算资源…

笔试-排列组合

应用 一个长度为[1, 50]、元素都是字符串的非空数组&#xff0c;每个字符串的长度为[1, 30]&#xff0c;代表非负整数&#xff0c;元素可以以“0”开头。例如&#xff1a;[“13”, “045”&#xff0c;“09”&#xff0c;“56”]。 将所有字符串排列组合&#xff0c;拼起来组成…