flutter 混合开发踩坑日记
- flutter与原生交互主要需要处理两个问题
①路由跳转
- 使用咸鱼的FlutterBoost(目前项目正在使用中...) 下载demo,移植部分代码即可使用
- 使用哈喽出行提供的解决方案flutter_thrio,据说内存处理上比咸鱼要做的好,还没有验证,目前更新频率很高,待日后稳定后可以试着用一下
- 使用消息通道MethodChannel,建立消息体系,通过发送消息的方式来跳转页面,这样做就需要自己去管理flutter引擎,需要让flutter引擎全局持有,这样才能每次打开页面的时候只在同一个引擎环境下操作,防止重复创建引擎造成的内存问题
②消息通道
- BasicMessageChannel通用数据传输,全双工,实时传递
- MethodChannel方法传递通道,传递只执行一次 全双工
- EventChannel事件监听通道持续监听如果电池电量的监听
这里只写MethodChannel写几个方法实现flutter与iOS的方法互调
在iOS中首先要创建消息通道并初始化通道名,这样后面所有消息都通过这个通道名对应的通道传递
//初始化通道
FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:@"MSGChannel" binaryMessenger:self.flutterViewController.binaryMessenger];
self.methodChannel = methodChannel;
//通过block回调监听通道中来自flutter的消息体 这里做一个dismiss方法,由于iOS中将flutter页面push出来,次数实现dismiss方法,给flutter发送dismss消息,就知道是让iOS将当前页面关闭的动作,iOS收到后,执行关闭操作
__weak typeof(self) weakself = self;
[methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
__strong typeof(weakself) strongself = weakself;
//dissmiss当前页面
if([call.method isEqualToString:@"dismiss"]){
[strongself dismissViewControllerAnimated:YES completion:nil];
}
if (result) {
result(@"成功关闭页面");
}
}];
//iOS中也可以主动给Flutter发消息通过invokeMethod 只需要注意消息通道名要跟初始化保持一致
[self.methodChannel invokeMethod:@"MSGChannel" arguments:@"我是iOS发送过来的消息"];
- 关于如何在现有项目中搭建混合开发环境,请参考往期文章 flutter 与iOS混合开发
- 通过咸鱼搭建的路由体系 MethodChannel需要在Flutter_boost初始化完毕后再初始化
//初始化flutter路由
PlatformRouterImp *router = [PlatformRouterImp new];
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterEngine *engine) {
//初始化消息通道
[[MSGChannelManager shareManager] setBinaryMessenger:engine.binaryMessenger];
//设置代理
[MSGChannelManager shareManager].delegate = self;
//发送消息测试
[[MSGChannelManager shareManager] sendEvent:@"push" arguments:@{@"abc":@"dcb"} result:nil];
}];
self.router = router;
MSGChannelManager在iOS环境下创建消息管理类,通过MSGChannelManager来创建消息通道,并全局持有
注意:binaryMessenger:从咸鱼初始化完成后拿到并在消息通道初始化的时候用到,Android也一样,否则,创建的消息通道无法实现互通
/// 收消息 并通道代理全局多转发
[methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
if([call.method isEqualToString:MSG_METHOD_NAME]){
NSDictionary *params = call.arguments;
NSString *name = params[@"name"];
NSDictionary *arguments = params[@"arguments"];
//消息转发
for (id delegate in self.delegateHash) {
if (delegate && [delegate respondsToSelector:@selector(msgChannel:name:arguments:)]) {
[delegate msgChannel:weakself.methodChannel name:name arguments:arguments];
} }
}else{
result(FlutterMethodNotImplemented);
}
}];
/// 发消息 通过MehodName
-(void)sendEvent:(NSString *)eventName
arguments:(NSDictionary *)arguments
result:(FlutterResult _Nullable)callback{
if(!eventName) return;
NSMutableDictionary *msg = [NSMutableDictionary new];
msg[@"name"] = eventName;
msg[@"arguments"] = arguments;
[self.methodChannel invokeMethod:MSG_METHOD_NAME
arguments:msg
result:callback];
}
-
通过Flutter_boost在iOS环境中,可以将Flutter页面放在Tabbar上,就比如咸鱼的个人中心模块,全部都是使用的flutter完成,这样也会相对带来一些坑
①项目中TabBar中有两个模块使用Flutter来完成,在使用过程中,由于在flutter中加入了webView,所以在info.plist中加入了io.flutter.embedded_views_preview=true 导致在两个flutter页面来回切换过程中闪屏严重,移除该字段后,能解决问题
②由后台切换到前台,导致原生页面莫名卡住,初步诊断认为可能是切换到后台后,系统会释放掉部分flutter引擎的一部分内存消耗,从而导致页面卡住不动,解决方法,让app进入后台后,仍然可以长期持有并保存,可以开启一个后台服务Background Modes,后台远程推送,或者后台播放音乐,让app保持活性
③将flutter页面作为二级页面,不放在Tabbar上,能够解决上面所有问题[😓] -
页面布局使用自定义StatefulWidget组件,发现页面值不更新的情况,通过设置UniqueKey()能够解决页面setsate不刷新的问题,原理请参考往期文章flutter StatefulWidget组件不刷新
-
flutter module模式下 pubspec.yaml最下面的androidPackage、iosBundleIdentifier保持默认就好,也不要跟原生项目保持一致,否则,生成的.android和.ios会和原生项目bundleId一样,这样,Android在打包时会出现包名重复等一些未知问题,所以请别手贱[dog],这两个参数是用来给生成的.android .ios生成默认包名和bundleId的
module:
androidX: true
androidPackage: com.example.flutter_xxxx
iosBundleIdentifier: com.example.flutter_xxxx
-
整个开发过程中发现iOS的问题比较多,Android的问题偏少,安卓需要处理好路由跳转问题,和页面销毁问题,iOS则会有页面闪屏,闪退,内存过爆,页面卡主等一系列问题
-
flutter在页面布局确实有他的优势,效率超级高,但是也有一些flutter自己的一些问题,如webView的处理问题,textField的输入问题,输入框不居中需要设置contentPading的问题,混合开发中初始化FlutterContoller会重复创建引擎问题,但是,后面随着flutter的更新迭代,我想这些问题也都会慢慢解决,但是带来的优势却是相当大的,开发周期缩短,人员成本减少等,后期还是无限看好flutter
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步