(原创)Flutter基础入门:手把手教你搭建Flutter混合项目

news2024/11/24 7:30:51

前言

Flutter是Google开源的构建用户界面(UI)工具包
支持在不同平台构建一致的ui效果
但在实际业务中,一般不会整个APP都用纯Flutter开发
尤其一些老的项目,会采用接入Flutter的方式来混合开发
那么今天就主要讲一下如何搭建一个Flutter的混合项目

混合项目实现方式

目前官方提供了两种方式添加依赖关系,他们的介绍分别如下:

方式一:模块代码依赖模式

这种方式是将flutter代码引入android项目,flutter代码对原生可见
好处是确保了一步完成Android项目和Flutter模块的编译。
对于同时涉及两个部分并且快速迭代很方便,
但这需要团队的每个人成员都安装Flutter SDK来确保顺利编译这个混合app。

方式二:AAR依赖模式

这种方式是将flutter代码打包成aar引入android项目,flutter代码对原生不可见
AAR模式有个好处就是团队中的其他成员不需要安装Flutter SDK,
最少只需要一个人输出AAR即可。

今天这篇博客主要讲方式一的实现,方式二的后面系列会讲

模块代码依赖模式实现

手动创建Flutter模块

首先我们新建一个简单的Android项目
然后进入到项目目录
打开cmd窗口,输入以下命令:

flutter create -t module --org com.xiongyp flutterxiongmodule

这样就创建了一个包名为com.xiongyp.flutterxiongmodule的Flutter模块
这里注意一点,Flutter模块放在其他目录下创建也是可以的
只要后面配置好地址,能链接到这个目录就好

引入Flutter模块

在Android项目的settings.gradle中将Flutter模块作为子项目引入
settings.gradle这样写:

rootProject.name = "FlutterHybridProject"
include ':app'
setBinding(new Binding([gradle: this]))                                           // 新增
evaluate(new File(                                                                // 新增
        settingsDir.parentFile,                                                   // 新增
        "${rootProject.name}/flutterxiongmodule/.android/include_flutter.groovy"  // 新增
))                                                                                // 新增
include ':flutterxiongmodule'

这里注意下:如果你的Flutter模块放在其他目录下
记得把include_flutter.groovy文件的路径配置准确
也就是这一行:

"${rootProject.name}/flutterxiongmodule/.android/include_flutter.groovy"

配置好了之后将settings.gradle的

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

改为:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

区别主要在:RepositoriesMode.PREFER_PROJECT
具体解释为:

FAIL_ON_PROJECT_REPOS :在项目的子 module 中配置仓库信息会导致编译失败。
PREFER_PROJECT:使用子 module 中配置仓库信息,忽略根目录中 settings 配置的仓库信息
PREFER_SETTINGS:使用根目录中 settings 配置的仓库信息,忽略子 module 中配置仓库信息

完成上面操作后,在project的build.gradle的

task clean(type: Delete) {
    delete rootProject.buildDir
}

上方添加:

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

完整的build.gradle的文件如下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

至此,大体上一个混合的Android原生+Flutter项目的初步构建就完成了。
接下来就是页面的跳转了

页面跳转

Android原生打开Flutter页面
默认的跳转方式会出现明显的白屏,体验上很不好,这里直接给出优化后的方式
使用FlutterEngine缓存并复用
1.在app的AndroidManifest.xml中注册FlutterActivity

<activity
    android:name="io.flutter.embedding.android.FlutterActivity"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:theme="@style/Theme.HybridFlutter"
    android:windowSoftInputMode="adjustResize" >
</activity>

2.在app中创建一个App.kt继承Application并在AndroidManifest.xml中配置给application节点的name属性

class App : Application() {
    ···
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xiongyp.flutterxiongmodule">

    <application
        android:name=".App"
        ···
</manifest>

3.在App.kt中准备好FlutterEngine
创建FlutterEngine实例

    private val flutterEngine by lazy {
        FlutterEngine(this).apply {
            dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
        }
    }

重写onCreate()并将实例存储在FlutterEngineCache中

override fun onCreate() {
    super.onCreate()

    FlutterEngineCache.getInstance().put("your_engine_id", flutterEngine)
}

重写onTerminate()并将实例销毁

override fun onTerminate() {
    super.onTerminate()

    flutterEngine.destroy()
}

在业务需要的地方使用FlutterEngine中的Intent实例进行跳转

    findViewById<TextView>(R.id.textView).setOnClickListener {
        startActivity(FlutterActivity.withCachedEngine("your_engine_id").build(this))
    }

选择app进行run,如果遇到如下Java版本问题,请进行如下配置变更

A problem occurred evaluating project ':flutter'.
> Failed to apply plugin 'com.android.internal.library'.
   > Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
     You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.

选择 Project Structure > SDK location > Gradle Settings 设置Gradle JDK为11
在这里插入图片描述
在./gradle.properties中添加上文中对应的java.home路径

# replace with your own jdk11 or above
org.gradle.java.home=C\:\\Softwares\\Google\\Android\\Android_Studio\\jre

sync后应该就可以顺利的运行你的项目了

导入Moudle

上面讲的是用flutter命令创建了FlutterMoudle然后引入到安卓工程
其实也可以用Android Studio来创建一个FlutterMoudle
下面讲两种用Android Studio来创建一个FlutterMoudle的方法

方式一

如下图:
在这里插入图片描述
之后输入Flutter module的Project name,选择Flutter SDK所在的路径,选择Flutter module的文件位置,最后输入Flutter module的描述,然后Next,如下图所示
在这里插入图片描述
上诉基本信息填充完毕后,点击Next,在弹出的面板中输入Flutter module的包名,如下图所示
在这里插入图片描述
输入Package name后点击Finish后Flutter module就正式创建完毕。
创建好的flutter module和新建的flutter项目在内容上基本没有差别。

方式二

当然,有的人会发现自己的Android Studio在创建Moudle时没有Flutter Moudle选项,如下图
在这里插入图片描述
估计是不同版本AS的区别,这时我们可以选择创建Flutter Project
在这里插入图片描述
选择下一步:
在这里插入图片描述
然后在下拉框里选择moudle,点击create就好了
在这里插入图片描述
注意,创建好的FlutterMoudle记得在Android项目的settings.gradle里配置好路径
你也可以直接放到Android项目的目录下,然后配置路径

gradle版本适配

上面讲的是Gradle7.X的项目如何集成FlutterMoudle进行混合开发
具体Gradle7.X有哪些改变,可以上网查下资料或参考下面博文:
gradle7 从上手到实践之上手体验
那么如果是老的项目,它的Gradle版本和写法是7.X之前的,就需要另外处理
这里也提一下
首先是settings.gradle文件,写法和之前差不多,全部内容如下:

rootProject.name = "FlutterHybridProject"
include ':app'
setBinding(new Binding([gradle: this]))                                // 新增
evaluate(new File(                                                     // 新增
        settingsDir.parentFile,                                              // 新增
        "${rootProject.name}/flutterxiongmodule/.android/include_flutter.groovy"  // 新增
))                                                                     // 新增
include ':flutterxiongmodule'

改动比较大的是build.gradle文件,这里也全部贴上来:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

至此,第一种搭建Flutter混合项目的方式就讲完了

源码使用

在你引用其他人的FlutterMoudle或者网上下载一些FlutterMoudle案例时
如果发现FlutterMoudle里面没有.android .ios .idea 等临时文件时
可以在FlutterMoudle文件夹下打开cmd控制台
输入以下命令:

flutter create .

回车后系统便会自动为你生成这些对应的临时文件了
这时你就可以正常运行项目并进行开发了!
参考解决方法:
Flutter 报错 ( Could not read script ‘xxx\flutter_tools\gradle\app_plugin_loader.gradle‘ )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/457078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0424作业

实现串口收发字符/字符串 uart4.c #include "uart4.h"void hal_uart_init() {//rcc初始化//使能CPIOB组控制器RCC->MP_AHB4ENSETR | (0x1 << 1);//使能CPIOG组控制器RCC->MP_AHB4ENSETR | (0x1 << 6);//使能UART4控制器RCC->MP_APB1ENSETR | …

Linux网路服务之PXE网络批量装机和Kickstart全自动化安装

文章目录 一 、PXE网络批量装机的简介和相关知识1.1 什么是PXE1.2搭建PXE 远程安装服务器1.3 PXE装机的过程描述 二、PXE批量安装的具体操作过程2.1安装并启用 TFTP 服务2.2安装并启用 DHCP 服务2.3准备 Linux 内核、初始化镜像文件2.4准备 PXE 引导程序2.5安装FTP服务&#xf…

Android分屏流程分析

本文基于Android 11。 SystemUI模块中的Divider管理着所有关于分屏的对象&#xff1a; DividerView&#xff08;分屏分割线&#xff0c;分屏显示界面&#xff09;SplitScreenTaskOrganizer&#xff08;分屏Task组织者&#xff0c;分屏逻辑&#xff09; 这里重点关注分屏逻辑…

有道CEO周枫:当我们谈论大模型时,应该关注哪些新能力?

作者&#xff1a;周枫 基于大语言模型技术的ChatGPT推出已经有4个月了&#xff0c;更多同类产品还在快速出现。比如&#xff0c;前天谷歌更新了Bard&#xff0c;将辅助编程能力支持的语言数量扩展到20种。 然而&#xff0c;对大模型技术的重要性也出现了质疑&#xff0c;前段…

开发框架之Furion

目录 概述 框架特点 功能模块 支持平台 运行环境 数据库 应用部署 Nuget框架扩展包 Nuget框架脚手架 FurionEFCore脚手架 FurionEFCore脚手架安装命令 FurionSqlSugar脚手架 FurionSqlSugar脚手架安装命令 使用脚手架 脚手架更新 概述 Furion是一个免费开源的.Ne…

【AI帮我写代码,上班摸鱼不是梦】调教ChatGPT过程全记录,让它帮我写程序!

最近发现磁盘空间严重不足&#xff0c;都弹窗提示我了&#xff1a; 想想看到底哪个文件夹占的空间比较大&#xff0c;好做针对性的删除和清理。奈何Windows系统没有查看文件夹大小的工具&#xff0c;只能鼠标放在某个文件夹上&#xff0c;等提示&#xff1a; AI时代都来临了&am…

PCL 点云变换

文章目录 一、原理简述1、旋转矩阵2、欧氏变换二、主要函数及代码实现1、主要函数2、完整代码3、效果实现参考文献:一、原理简述 两片点云的刚体变换包含旋转和平移,变换矩阵的含义如下: 1、旋转矩阵 绕 x x

Promise异步编程

目录 一、Promise的含义 二、基本用法 三、reject的用法 四、执行顺序 五、 项目中使用promise获取后端数据 六、catch的用法 七、finally的用法 八、Promise.all() 九、Promise.all()有一个是失败 十、Promise.race()全部是成功 十一、Promise.race()有一个是失败 一、…

Java——二叉树中和为某一值的路径(二)

题目链接 牛客网在线oj题——二叉树中和为某一值的路径&#xff08;二&#xff09; 题目描述 输入一颗二叉树的根节点root和一个整数expectNumber&#xff0c;找出二叉树中结点值的和为expectNumber的所有路径。 1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过…

图的相关知识总结

目录 图的概念图的存储结构邻接矩阵邻接表 图的遍历最小生成树Kruskal算法prim算法 最短路径问题单源最短路径--Dijkstra算法-单源最短路径--Bellman-Ford算法多源最短路径--Floyd-Warshall算法 图的概念 图是有顶点集合以及顶点间的关系组成的一种数据结构:G(V,E),其中顶点集…

JS-11A/224时间继电器 JOSEF约瑟 板前、板后接线

系列型号&#xff1a; JS-11A/11集成电路时间继电器&#xff1b;JS-11A/12集成电路时间继电器&#xff1b; JS-11A/13集成电路时间继电器&#xff1b;JS-11A/136集成电路时间继电器&#xff1b; JS-11A/137集成电路时间继电器&#xff1b;JS-11A/22集成电路时间继电器&#…

Java基础(十二)Java比较器

1 Java 比较器 我们知道基本数据类型的数据&#xff08;除boolean类型外&#xff09;需要比较大小的话&#xff0c;直接使用比较运算符即可&#xff0c;但是引用数据类型是不能直接使用比较运算符来比较大小的。那么&#xff0c;如何解决这个问题呢&#xff1f; 在Java中经常…

Jomalone(“独狼”)的Rootkit后门dll分析

从England.sys&#xff08;md5为B5F7DE342B1D661E57BCD14615CADEFA&#xff09;驱动文件中提取了4个dll文件&#xff0c;其中两个64位dll&#xff0c;两个32位dll&#xff0c;主要用于APC注入 样本的基本信息 文件名称: 0x3df60-0x15e00.dll 文件大小: 87.5 KB (89,600 字节) …

Kubeadm方式搭建K8s集群【1.23.0版本】

文章目录 一、初始化准备二、安装kubeadm三、初始化Master集群四、将新的Node节点加入集群五、部署CNI网络插件六、其他配置 Kubernetes1.24(包括1.24)之后不在兼容docker,如果有需要兼容docker的需求&#xff0c;则安装一个 cri-docker的插件&#xff0c;本文使用的是kuberne…

【SWAT水文模型】ArcSWAT输入准备

ArcSWAT输入准备 1 必需的ArcSWAT空间数据集1.1 数字高程模型&#xff08;DEM&#xff09;1.2 土地覆盖/土地利用类型1.3 土壤数据 2 可选的ArcSWAT空间数据集2.1 DEM Mask2.2 Streams2.3 User- Defined Watersheds 3 ArcSWAT表格和文本文件3.1 子流域出口位置表(dBase 表)3.2 …

【MCAL_Uart】-1.1-图文详解Uart串口协议

目录 1 什么是UART 2 UART的电平 3 UART的波特率 4 UART帧格式 4.1 start bit起始位 4.2 data bit数据位 4.3 parity bit奇偶校验位 4.4 stop bit停止位 5 什么是8-N-1 6 UART总线负载率计算 结尾 优质博文推荐阅读&#xff08;单击下方链接&#xff0c;即可跳转&am…

shell脚本基础之详解脚本的控制

详解脚本的控制 信号的处理Linux信号生成信号中断进程暂停进程 捕获信号捕获脚本退出修改或移除捕获 以后台模式运行脚本后台运行脚本运行多个后台脚本 在非控制台下运行脚本作业控制 查看作业重启停止的作业调整谦让度nice命令renice命令 定时运行作业用 at 命令来定时执行作业…

2023移动云大会即将召开,划重点来了

今年由 ChatGPT 引起的AI浪潮下&#xff0c;人们热议其背后的算力问题&#xff0c;毋庸置疑&#xff0c;算力已成为和水电同样重要的资源。作为开发者&#xff0c;如何了解云计算领域有哪些最新发展趋势&#xff1f; 4月25-26日&#xff0c;以“云擎未来&#xff0c;智信天下”…

Scala之集合(3)

目录 WordCount案例&#xff1a; 需求分析与步骤&#xff1a; 拆分&#xff1a; 聚合&#xff1a; 格式转化&#xff1a; 方法1&#xff1a; 方法2&#xff1a; 排序&#xff1a; 方法1&#xff1a; 方法2&#xff1a; 取top3&#xff1a; 整体化简后的代码&#xf…

轻量级服务器nginx:配置虚拟主机的两种方式

虚拟主机是指&#xff0c;在一台服务器中&#xff0c;通过nginx的代理&#xff0c;我们可以访问多个网站。区分不同的网站&#xff0c;可以通过端口、域名两种方式 这里写目录标题 一 端口不同区分不同的虚拟主机二 通过域名区分不同的主机名1.配置域名映射2.显示登录效果 一 …