8000 When disposing of a FlutterEngine while a PlatformView is being displayed, gestures on other FlutterEngines no longer work. · Issue #127168 · flutter/flutter · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
When disposing of a FlutterEngine while a PlatformView is being displayed, gestures on other FlutterEngines no longer work. #127168
Closed
flutter/engine
#43652
@keisuke-kiriyama

Description

@keisuke-kiriyama

Is there an existing issue for this?

Steps to reproduce

  1. Generate the first FlutterEngine using FlutterEngineGroup and initialize a FlutterViewController for the initial display.
  2. Display a PlatformView within the generated first FlutterViewController.
  3. Transition to a native ViewController using MethodChannel.
  4. Generate the second FlutterEngine using FlutterEngineGroup and transition to the second FlutterViewController.
  5. Display a PlatformView within the second FlutterViewController.
  6. Pop the second FlutterViewController and the native ViewController, returning to the first FlutterViewController.

Expected results

You can interact with the first FlutterViewController.

Actual results

Gestures are not recognized, and it becomes unresponsive in the first FlutterViewController.

Code sample

AppDelegate.swift
import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    let engines = FlutterEngineGroup(name: "multiple-flutters", project: nil)
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        window = UIWindow(frame: UIScreen.main.bounds)
        let navigationController = UINavigationController(rootViewController: MyFlutterViewController(withEntrypoint: nil))
        window?.rootViewController = navigationController
        window?.makeKeyAndVisible()
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}
MyFlutterViewController
import Flutter

class MyFlutterViewController: FlutterViewController {
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    init(withEntrypoint entryPoint: String?) {
        let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
        let newEngine = appDelegate.engines.makeEngine(withEntrypoint: entryPoint, libraryURI: nil)
        GeneratedPluginRegistrant.register(with: newEngine)
        super.init(engine: newEngine, nibName: nil, bundle: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let methodChannel = FlutterMethodChannel(
            name: "methodChannel",
            binaryMessenger: self.binaryMessenger
        )
        methodChannel.setMethodCallHandler({[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
            guard let self = self else { return }
            switch call.method {
            case "transitionToNativePage":
                let viewController = MyViewController()
                self.navigationController?.pushViewController(viewController, animated: true)
            default:
                result(FlutterMethodNotImplemented)
            }
        })
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden(true, animated: true)
    }
}
MyViewController.swift
import UIKit

class MyViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        let button = UIButton(type: .system)
        button.setTitle("Show Flutter Screen", for: .normal)
        button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
        self.view.addSubview(button)
        
        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.setNavigationBarHidden(false, animated: true)
    }
    
    @objc func buttonTapped(_ sender: Any) {
        let viewController = MyFlutterViewController(withEntrypoint: "platformViewMain")
        self.navigationController?.pushViewController(viewController, animated: true)
    }
    
}
main.dart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';

enum EntryPoint {
  main,
  platformView,
}

Future<void> main() async {
  runApp(const MainApp());
}

@pragma('vm:entry-point')
Future<void> platformViewMain() async {
  runApp(const PlatformViewApp());
}

class MainApp extends StatelessWidget {
  const MainApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MainPage(),
    );
  }
}

class MainPage extends StatelessWidget {
  const MainPage({Key? key}) : super(key: key);

  static const methodChannel = MethodChannel('methodChannel');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('MainPage'),
      ),
      body: Center(
        child: ListView(
          children: [
            TextButton(
              child: const Text('Transition to native page'),
              onPressed: () async {
                await methodChannel.invokeMapMethod('transitionToNativePage');
              },
            ),
            const SizedBox(height: 20),
            TextButton(
              child: const Text('Transition to platformView page'),
              onPressed: () async {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) {
                      return const PlatformViewPage(
                          entryPoint: EntryPoint.main);
                    },
                  ),
                );
              },
            )
          ],
        ),
      ),
    );
  }
}

class PlatformViewApp extends StatelessWidget {
  const PlatformViewApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const PlatformViewPage(entryPoint: EntryPoint.platformView),
    );
  }
}

class PlatformViewPage extends StatelessWidget {
  const PlatformViewPage({
    required this.entryPoint,
    Key? key,
  }) : super(key: key);

  final EntryPoint entryPoint;

  static final controller = WebViewController()
    ..loadRequest(Uri.parse('https://flutter.dev'));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('PlatformView Page'),
        leading: entryPoint == EntryPoint.platformView
            ? BackButton(
                onPressed: () => SystemNavigator.pop(animated: true),
              )
            : null,
      ),
      body: WebViewWidget(
        controller: controller,
      ), // This issue can be reproduced with PlatformViews such as GoogleMap or WebView.
    );
  }
}
pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.2.0

Logs

No error logs are specifically displayed.

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.3, on macOS 12.6.1 21G217 darwin-arm64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.1)
[✓] VS Code (version 1.78.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

• No issues found!

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work lista: platform-viewsEmbedding Android/iOS views in Flutter appsc: crashStack traces logged to the consoleengineflutter/engine repository. See also e: labels.found in release: 3.10Found to occur in 3.10found in release: 3.11Found to occur in 3.11has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-iosiOS applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-iosOwned by iOS platform teamtriaged-iosTriaged by iOS platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0