Flutter模块集成iOS原生应用后无法完全关闭问题咨询
解决Flutter模块集成iOS后再次打开停留在之前页面的问题
原因分析
复用同一个FlutterEngine时,Flutter的路由栈和应用状态会被持久化保存,因此关闭模块再打开时会回到之前的页面。销毁Engine无效通常是因为实例未被正确释放,或是销毁时机不合理。
解决方案
方案1:每次打开时创建全新的FlutterEngine和FlutterViewController
不再复用全局Engine,每次打开Flutter模块都初始化新实例,确保每次都是全新的Flutter运行环境:
// 打开Flutter模块的代码 FlutterEngine *newFlutterEngine = [[FlutterEngine alloc] initWithName:@"new_flutter_engine"]; [newFlutterEngine run]; FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:newFlutterEngine nibName:nil bundle:nil]; // 配置MethodChannel FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.sara.app/myAppChannel" binaryMessenger:flutterViewController.binaryMessenger]; [channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) { if([call.method isEqualToString:@"exitUpiModule"]) { [flutterViewController dismissViewControllerAnimated:YES completion:^{ // 销毁Engine,释放资源 newFlutterEngine = nil; }]; } }]; [self presentViewController:flutterViewController animated:YES completion:nil];
方案2:关闭时重置Flutter路由栈
若需要复用Engine,可在关闭模块前通过MethodChannel通知Flutter侧清空路由栈,回到初始页面:
- Flutter侧代码:
final MethodChannel _channel = MethodChannel('com.sara.app/myAppChannel'); @override void initState() { super.initState(); _channel.setMethodCallHandler((call) async { if (call.method == 'resetRoute') { // 回到首页并清空所有路由 Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (context) => const HomePage()), (route) => false, ); } }); }
- iOS侧修改关闭逻辑:
[channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) { if([call.method isEqualToString:@"exitUpiModule"]) { // 先通知Flutter重置路由 [channel invokeMethod:@"resetRoute" arguments:nil result:^(id _Nullable result) { // 路由重置完成后关闭页面 [flutterViewController dismissViewControllerAnimated:YES completion:nil]; }]; } }];
方案3:打开Flutter模块前重置路由
每次打开FlutterViewController前,通过已复用的Engine对应的MethodChannel通知Flutter重置路由:
FlutterEngine *flutterEngine = ((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine; // 先通知Flutter重置路由 FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.sara.app/myAppChannel" binaryMessenger:flutterEngine.binaryMessenger]; [channel invokeMethod:@"resetRoute" arguments:nil result:^(id _Nullable result) { // 路由重置后创建并打开FlutterViewController FlutterViewController *flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil]; // 重新设置MethodChannel回调 [channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) { if([call.method isEqualToString:@"exitUpiModule"]) { [flutterViewController dismissViewControllerAnimated:YES completion:nil]; } }]; [self presentViewController:flutterViewController animated:YES completion:nil]; }];
内容的提问来源于stack exchange,提问作者Sara Lisa
相关产品推荐
相关产品推荐

