简单集成flutter到已有项目
创建Flutter Module
flutter的集成可以是创建一个 新的flutter app
的方式,也可以是以创建一个module的方式,集成到一个已有的App中。一般项目都会通过第二种方式,来逐步进行Native和Flutter代码的混编。这里也主要是采用第二种方式,来一步步演示集成步骤。
这种集成方式要求flutter侧的代码是通过module的方式来创建,所以先创建一个示例的module。运行下面创建代码
1 | ~/Desktop/demo ⍉ |
之后会生成一个flutter_module的文件夹,里面就是我们要集成的flutter module。创建好之后, 模板已经生成了一个最简单的界面。我们先把这个module放到一边,先到App中尝试把它集成进来。
Native端集成Flutter module
创建iOS项目Demo工程
这里我们先预先创建了一个单视图的iOS Demo项目。谷歌推荐使用cocoapod来集成flutter模块。由于Demo工程如果还没有Podfile,就需要先创建一个Podfile。注意要开启use_frameworks!
1 | source 'https://github.com/CocoaPods/Specs.git' |
之后执行pod install
,生成项目的workspace。
Podfile中加入对flutter module的依赖
往已有的App中集成flutter module时又有两种方式,一种是通过源码的方式集成,这种要求开发者机器上装有flutter开发环境。另一种是把flutter模块的代码打包成framework,然后添加到目的app中。为了方便演示,这里采用第一种。
首先往Podfile里增加导入flutter的代码,加之后Podfile是这个样子。
1 | source 'https://github.com/CocoaPods/Specs.git' |
加完后重新执行一次pod install
,之后就可以看到项目的Pod工程里多了Development Pods.
其中,Flutter是引擎相关代码,flutter_module是业务相关dart,我们开发的dart代码就被编译在这个framework里。FlutterPluginRegistrant是注册flutter插件用的。
Native项目代码里使用Flutter module
首先需要创建Flutter Engine。方便起见,我们直接在AppDelegate.h中声明
1 |
|
在App启动后,及时初始化一下Flutter引擎。当然也可以在后续要用到Flutter界面的时候才初始化,但那可能会造成Flutter界面展现时的一点卡顿,所以可以尽早初始化。
1 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
准备好引擎之后,我们就已经可以在需要的地方展现Flutter模块界面了。Flutter的界面都是通过framework中提供的FlutterViewController
来加载的。 下面通过在一个vc中加入一些测试代码,来展现刚才模板中创建的flutter界面。
1 | - (void)viewDidLoad { |
顺利的话,点击一下vc,就可以看到Flutter module中的界面展现出来了。
使用flutter_boost来混合开发
目前展现的是模板生成的主界面,但项目中的混编应用会远比这复杂,可能会有多个flutter界面,并且跟Native交互也更复杂。通过Boost插件来更好的实现原生和Flutter的混合开发,这里做个简单例子。
flutter_module部分
创建子页面
先打开刚才创建的flutter_module,准备一个要加载的子页面
业务开发的dart代码一般都放在lib文件下,先在lib目录下创建一个subpage.dart
的文件,作为后续要加载的一个普通的子页面。简单创建一个 SubPage.dart
1 | import 'package:flutter/material.dart'; |
增加flutter_boost第三方package
打开module工程里的pubspec.yaml
文件,flutter对第三方库的依赖是通过这个文件来管理的,类似于oc项目中的Podfile。我们在其中加入对flutter_boost的依赖
1 | dependencies: |
之后在terminal中当前目录下执行flutter pub get
命令行。用VSCode时,每次保存这个文件时这个命令也会自动触发。
flutter_boost添加完成后,我们就可以设置对它子页面的路由管理。
module中使用flutter_boost
打开main.dart
,首先增加flutter_boost的dart导入
1 | import 'package:flutter_boost/flutter_boost.dart'; |
然后把下面_MyHomePageState
类的实现代码全部删掉,这些模板创建的代码已经用不到了,改成以下这样。关键是增加通过FlutterBoost
来管理页面路由的代码
1 | class _MyHomePageState extends State<MyHomePage> { |
接下来再给FlutterBoost注册一下我们的子页面,这部分代码我们放在_MyHomePageState的initState()
方法中去做。
1 | void initState() { |
做完这些后,flutter_module这部分就暂时完成了,接下来就可以去App中使用FlutterBoost接入了
Native端
Native端也增加flutter_boost的依赖
因为flutter端使用了flutter_boost插件,并且代码有了改动,所以在Terminal中重新执行一次pod install
。可以看到Native这边也增加上了flutter_boost相关的pod库。
1 | Analyzing dependencies |
Native端主要可以分成两个部分:flutter_boost的初始化,以及与flutter端的交互。
我们看看与flutter端的交互部分。
添加flutter_boost对路由跳转的平台实现
flutter_boost的实现机制,个人理解大致是每个flutter中的页面都通过Native这边的一个FLBFlutterViewContainer
来承载。而FLBFlutterViewContainer
都共享同一个FlutterEngine。FLBFlutterViewContainer
的展现和消失,不论是Native端发起还是Flutter端发起,最后都是Native端来实现的。具体可以参考flutter_boost的介绍
首先创建一个FlutterPlatform
的类,实现FLBPlatform
协议,来实现flutter端发起的跳转请求。
1 | @import flutter_boost; |
初始化flutter_boost
对FLBFlutterViewContainer
的协作处理类建立好之后,我们就可以去进行flutter_boost的初始化了。由于它会接管FlutterEngin的创建,所以我们之前的Engine初始化代码需要修改一下。回到AppDelegate类中,将之前的FlutterEngine初始化代码都删掉,换成flutter_boost提供的初始化方式.
1 | FlutterPlatform* platform = [[FlutterPlatform alloc] init]; |
通过flutter_boost打开Flutter中的子页面
到这里,通过flutter_boost来接入flutter就已经基本完成了。我们可以来试着通过flutter_boost来打开我们刚才创建的subpage页面。还是在我们前面添加点击事件的地方,换成以flutter_boost的方式打开
1 | - (void)onTap |
没意外的话,应该可以看到我们创建的子页面被展现出来了。
Flutter中调用关闭当前子页面
但是目前展现,不能回退,返回去再修改一下dart代码,在界面上增加一个返回按钮。通过flutter_boost来退出该界面了。修改subpage的代码,在Appbar上增加一个返回按钮
1 | appBar: AppBar( |
顺利的话,点击新加的返回按钮,就可以正常退出了。
最后
上面记录的是一个最基本的接入流程,方便自己后续学习。后面还有很多细节需要根据项目需要去调整,比如插件的注册,路由跳转的平台实现等等。