解决Flutter_boost [FBFlutterContainerManager activeContainer:forUniqueId] 闪退

747 阅读1分钟

前言

很多公司在接入flutter时考虑到风险以及开发成本,都选择部分接入而不是整体替换原生App, 闲鱼推出的Flutter_boost 给原生App提供了混合flutter的容器能力。

本文主要介绍在iOS在使用flutter_boost时,页面通过FBFlutterContainerManager 维护字典,通过 uniqueId key-value的形式查找contaier,具体原理后续会做解析。

问题描述:

  • A、B页面为FBFlutterViewContainer
  • A present B, A 可以 调用dismiss, B 也可以调用dismiss, ,两者调用dimiss都会关闭B
  • 如果 A 作为父节点,B则是子节点,A 的presentingVC 则为null
  • 当A调用dismissViewControllerAnimated, B页面返回, FBFlutterViewContainer 内部 dismissViewControllerAnimated:(BOOL)flag completion: 被调用, 页面销毁,
//当VC被dismiss时,就通知flutter层销毁page
[self detachFlutterEngineIfNeeded];
[self notifyWillDealloc];
  • A页面被dismiss,并从 allContainers 中移除, A页面被激活后,就会导致FBFlutterContainerManager activeContainer:forUniqueId 方法崩溃

解决方案:

判断下 self.presentingViewController 是否为null,如果null 则不销毁页面,为null 则代表当前页面A 为父节点,不能被销毁

- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
    BOOL isDismissed = self.presentingViewController ? YES : NO;
    [super dismissViewControllerAnimated:flag completion:^(){
        if (completion) {
            completion();
        }
        if (isDismissed) {
            [self detachFlutterEngineIfNeeded];
            [self notifyWillDealloc];
        }
    }];
}

总结

以上是临时解决方案,从我们使用场景来看可以暂时解决此问题,已经给Flutter_boost提交PR, 期待官方后续能给出更合适的解决方案

未经作者允许,禁止转载