最近在集成flutter进项目
创新互联长期为上1000家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为蒲城企业提供专业的成都做网站、网站制作,蒲城网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。
以收集编译产物并以cocopods方式集成
产物大概放入两个pod库
这个暂且叫pod1,pod1放flutter.framework,第三方plugin.a,自己写的基础plugin,比如networking,hud等等(由于是混编,不可避免存在很多原生基础组件,所以能公用的基础组件都会弄一个flutter-plugin桥接)
第二个pod2放编译之后的app.framwork,注册文件GeneratedPluginRegistrant,以及各个业务模块.a(有可能没有)结构大概如下面
podspec大概如下
主工程引入这两个pod库即可
接下来从零开始搭建上文所说的
先创建一个flutter module
这个是主flutter工程,用来集成businessModule以及生成app.framework
结构如下图
再生成一个业务工程
注意此时还需要进入example生成ios和Android工程,不然无法单独编译运行
这样 这个单独的业务模块就可以单独跑起来了
此时主flutter工程和业务工程均搭建完毕
在主工程pubspec.ymal文件讲两个工程关联
好了 接下来就是编写脚本收集产物了
编译完成之后会在flutter主工程product生成如下文件
将上面文件分类收集做成文章开头的pod1,pod2 ,在native工程引入即可
在集成flutter的过程中 踩不少坑 也阅读很多前辈的文章,在此一并感谢
在Flutter内部机制中,默认使用自动管理导航机制,该机制在Flutter与原生混和开发情况下,Flutter页面不一定作为项目的首页面,所以出现需要在首个Flutter页面使用导航返回的需求。
Flutter的AppBar中定义有属性:
该属性默认为YES,即默认为自动管理导航栏,该情况下其会在非第一个Flutter页面创建导航返回按钮,我们在AppBar中将其设置为false:
并且手动添加导航返回按钮:
完成
新一代Flutter-Native混合解决方案。 FlutterBoost是一个Flutter插件,它可以轻松地为现有原生应用程序提供Flutter混合集成方案。FlutterBoost的理念是将Flutter像Webview那样来使用。在现有应用程序中同时管理Native页面和Flutter页面并非易事。 FlutterBoost帮你处理页面的映射和跳转,你只需关心页面的名字和参数即可(通常可以是URL)。
在配置文件pubspec.yaml中加入依赖:
或
主要实现一个类FlutterRouter.swift
在flutter官网上推荐了iOS项目中两种混编方式:
笔者在采用两种集成方式的过程中,因为iOS项目结构设计导致这两种简单的集成方式都有些麻烦,所以在实践中更改和优化了集成方式,使之在笔者的项目中能够更加简单和快速的集成。
问题:在不更改flutter tool中相关脚本的前提下,添加的Script Phase中的脚本相对路径错误,如果只是开发,手动更改下路径就可以了,但是在考虑到CI中不能每次在pod install之后都去更改,所以在开发调试中采用该集成方式,结合flutter attach的方式去调试。
通过编译相关的 xcframework + Cocoapods私有库的集成方式在CI中集成,这样QA的CI不需要配置flutter的相关依赖
根据flutter编译工具的提示: 上面的编译命令是打包flutter工程项目和插件的产物,在实际开发过程中可以发现是否引入了依赖Native的插件会导致贬义编译产物的不同。
根据上面的对比:
第一部分:基础的 Flutter Engine + Flutter App 编译后的产物 Flutter.xcframwork -- Flutter引擎的包 App.xcframework -- 工程项目对应的AOT的编译产物 第二部分:三方插件的注册中心 FlutterPluginRegistrant.xcframework -- 第三方插件的注册中心,其实是Native + iOS通信的集合 第三部分:依赖iOS Native的原生 FMDB . xcframwork path_provider_ios.xcframework sqflite.xcframework -- cached_network_image依赖的原生实现
根据上面的编译产物可以知道Flutter和App是编译后必有的包,后面的两个部分完全是服务于三方插件的,到这可以解答第二个问题:笔者App的混编过程中混编插件失效是因为笔者在NativeApp中重写了Flutter的容器,使用了FlutterEngineGroup动态创建多引擎去对应进入不同的功能模块,混合插件是因为重写过程中没有通过GeneratedPluginRegistrant注册插件,所以需要在Native的Flutter容器中注册插件,使之生效。
在这为什么使用commit的hash作为flutter-libs的依赖,因为pod install的时候会有缓存,除了版本好,commit hash也能保证每次CI编译通过 pod install 来更新flutter-libs依赖产物
完成!!!
如果我们目前的项目是Android的,但是接下来我们希望部分页面可以使用Flutter进行开发,甚至我们希望在Native页面中嵌入FlutterUI组件,那么我们该如何实现呢?
假设你现在Android项目的目录的结构是这样的
这时候如果你想创建一个Flutter模块,使得Android模块和Flutter模块之间可以进行交互,我们可以通过Android Studio新建一个Flutter Module,具体过程是:File — New — New Module ,之后选择Flutter Module,指定Project Location的路径为
也就是说,最终你的项目结构会是这样的
接下来在Android Module的 build.gradle 文件中添加flutter依赖
先创建一个Flutter页面
这里比较重要的是 window.defaultRouteName 这个字段,这个字段可以接收从Native传递过来的参数 (下文我们会介绍原生传递参数的方法),也就是说通过这个字段我们就可以进行Flutter页面的路由的分发
我们可以直接在Android的 MainActivity 中启动一个 FlutterActivity ,这里的 initialRoute 方法中传递的参数就对应Flutter层的 window.defaultRouteName
注意:需要在 AndroidManifest.xml 注册 FlutterActivity
自己创建一个 FlutterAppActivity 继承自 FlutterActivity
在 MainActivity 中启动 FlutterAppActivity (另外别忘了在 AndroidManifest.xml 中注册 FlutterAppActivity )
两种启动方式的区别
如果单纯只是想打开一个Flutter页面,两种方式实际上基本没有太大区别,第一种方式也许还会更简单一点。但是,在Flutter开发中,我们往往还需要开发一些Native插件供Flutter调用,如果使用复写 FlutterActivity 的方式更有利于我们在 FlutterActivity 中注册我们的Native插件,所以实际开发中一般推荐使用第二种方式
扩展思考
initialRoute 从名称上看起来是Flutter提供给我们进行Native与Flutter交互的路由跳转的,但是实际上他就是一个字符串,我们不仅仅可以传递一个路由名称,有时候我们也可以通过这个参数传递一串JSON数据,然后在Flutter端进行解析,这样我们就可以通过这个参数做更多的事情
activity_main.xml
FrameLayout 用于承载Flutter组件
MainActivity.java
使用 FragmentManager 将 FlutterFragment 添加到 FrameLayout 容器中
运行结果
上半部分是原生的TextView,下半部分是Flutter的Text组件
本节主要介绍了Native和Flutter之间的页面跳转,以及同一个页面中Native与Flutter组件的组合。接下来会介绍如何编写Android插件与Flutter进行数据交互
Uniapp目前比较成熟,而且用的是Vue语法,学习成本比较低,而且行业里面用的也比较广泛,而Flutter的话,学习成本略高,因为要学习新的语言,还有就是目前生态不是特别完备,等他再发展发展吧。目前黑马程序员就有学习Vue的视频,你可以去学习一下,提高自己的能力,让自己的职场更好!您的采纳给我提供源源不断的动力,很高兴您能满意