原生项目集成flutter流程这里不做说明
FlutterEngineGroup
在推出后,很好的解决了原生跳转多flutter页面的路由问题,可以非常容易的实现native->flutter->native->flutter
这种嵌套路由,只需要重新创建一个flutterEngine
,并且开销很小
1. 创建FlutterEngineGroup
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.flutterEngineGroup = [[FlutterEngineGroup alloc] initWithName:@"flutterGroupName" project:nil];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
2. 创建FlutterViewController
@interface MyFlutterViewController : FlutterViewController
-(instancetype)initWithFlutterUrl:(NSString *)url;
@end
@implementation MyFlutterViewController
-(instancetype)initWithFlutterUrl:(NSString *)url {
FlutterEngineGroup *engineGroup = [AppDelegate getFlutterEngineGroup];
FlutterEngine *engine = [engineGroup makeEngineWithEntrypoint:nil libraryURI:nil initialRoute:url];
return [self initWithEngine:engine nibName:nil bundle:nil];
}
@end
这样就实现了多engine的路由跳转
但是FlutterEngineGroup
一个弊端就是Engine
与Engine
之间数据是隔离的,没有办法直接通信,这里我采用原生平台作为中转站,通过channel
先通知原生平台,再由原生平台来通知到其他的flutterEngine
首先要说明的是因为flutterEngine
是相互隔离的,所以注册的channel
也是隔离的
3. 创建Engine-Channel键值对管理类
把目前还在路由栈中的engine以及对应的channel对应保存起来,这里我使用NSMapTable
,原因是NSMapTable
的key
不需要遵守NSCopying
协议,并且可以设置keyValue的引用类型,当设置为weak引用,当engine销毁后,对应的键值对会自动回收
先创建一个flutterManage用来管理Engine-Channel
键值对,作为一个单例,提供添加以及遍历通知的方法
@interface FlutterManage : NSObject
+ (instancetype)shared;
- (void)setObject:(FlutterMethodChannel *)anObject forKey:(FlutterEngine *)aKey;
-(void)notifyOtherFlutterEngineWithEngine:(FlutterEngine *)engine info:(id)info;
@end
static FlutterManage *_manage = nil;
@interface FlutterManage ()
@property(nonatomic, strong) NSMapTable<FlutterEngine *,FlutterMethodChannel *> *table;
@end
@implementation FlutterManage
+ (instancetype)shared {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_manage = [[self alloc] init];
_manage.table = [NSMapTable weakToWeakObjectsMapTable];
});
return _manage;
}
-(void)setObject:(FlutterMethodChannel *)anObject forKey:(FlutterEngine *)aKey {
[_table setObject:anObject forKey:aKey];
}
-(void)notifyOtherFlutterEngineWithEngine:(FlutterEngine *)engine info:(id)info {
FlutterMethodChannel *channel = [_manage.table objectForKey:engine];
NSEnumerator *enumerator = [_manage.table objectEnumerator];
FlutterMethodChannel *target;
while (target = [enumerator nextObject]) {
if (target == channel) continue;;
[target invokeMethod:@"notifyOtherFlutterEngine" arguments:info];
}
}
@end
4. 在MyFlutterViewController中保存engine-channel
键值对,并且在收到通知消息notifyOtherFlutterEngine
后调用管理类的通知方法
-(void)initChannel {
__weak typeof(self) weakSelf = self;
self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"my_methodChannel" binaryMessenger:self.binaryMessenger];
[self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
if ([call.method isEqualToString:@"notifyOtherFlutterEngine"]) {
[[FlutterManage shared] notifyOtherFlutterEngineWithEngine:weakSelf.engine info:call.arguments];
}
}];
[FlutterManage.shared setObject:self.methodChannel forKey:self.engine];
}
到此,实现了多引擎之间的数据传递
我觉得通道有这一个就可以了,后面如果需要细分不同的通知做不一样的逻辑,我们可以再info中扩展参数,这样就不必每次有新的通知类型,都去修改FlutterManage
这个类,扩展只限制在业务层
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...