Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating and destroying multiple maps causing other maps to throw PlatformException(channel-error, Unable to establish connection on channel., null, null) #17

Closed
LjubiTech-Maxko opened this issue Dec 27, 2022 · 5 comments · Fixed by #72
Assignees
Labels
bug Something isn't working

Comments

@LjubiTech-Maxko
Copy link
Contributor

LjubiTech-Maxko commented Dec 27, 2022

When we have initial screen which contains map, and we push and pop a route with other map, calling functions on map which is on initial screen throws PlatformException. Generally creating and destroying map even without pushing and popping routes is causing the same exception. For example, we have a widget which is initially off screen, and when user clicks a button, widget slides in and displays a map which is destroyed when the user is finished with that widget.

Reproduction code:

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  MapboxMap? _map;
  bool _styleLoaded = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Map'),
      ),
      body: Stack(
        children: [
          MapWidget(
            resourceOptions: ResourceOptions(accessToken: <add access token>),
            styleUri: MapboxStyles.LIGHT,
            onMapCreated: (MapboxMap map) => _map = map,
            onStyleLoadedListener: (StyleLoadedEventData event) => _styleLoaded = true,
          ),
          Positioned(
            left: 16,
            bottom: 16,
            child: ElevatedButton(
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const SecondRoute()),
              ),
              child: const Text('Second map'),
            ),
          ),
          Positioned(
            right: 16,
            bottom: 16,
            child: ElevatedButton(
              onPressed: () {
                if(_styleLoaded) {
                  _map!.style.styleLayerExists('layer_id');
                }
              },
              child: const Text('Map action'),
            ),
          ),
        ],
      ),
    );
  }
}

class SecondRoute extends StatelessWidget {
  const SecondRoute({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Map'),
      ),
      body: MapWidget(
        resourceOptions: ResourceOptions(accessToken: <add access token>),
        styleUri: MapboxStyles.LIGHT,
      ),
    );
  }
}

Steps to reproduce:

  1. Click on Second Map button.
  2. Go back to previous screen.
  3. Click on Map action button.

Following exception is thrown:

E/flutter (27096): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)
E/flutter (27096): #0      StyleManager.styleLayerExists (package:mapbox_maps_flutter/src/pigeons/map_interfaces.dart:5766:7)
E/flutter (27096): <asynchronous suspension>
@yunikkk yunikkk self-assigned this Jan 5, 2023
@yunikkk yunikkk added the bug Something isn't working label Jan 5, 2023
@dawid-niedzwiecki
Copy link

dawid-niedzwiecki commented Jan 11, 2023

Same issue here, pushing one view with a map on top of another view with a map, it raises that exception.

May I ask when this issue is estimated to be resolved?

In the meantime - are there any known workarounds?

@yunikkk
Copy link
Collaborator

yunikkk commented Feb 3, 2023

@LjubiTech-Maxko @dawid-niedzwiecki I assume it's related to the multimap setup and #54, looking as well.

@LjubiTech-Maxko
Copy link
Contributor Author

LjubiTech-Maxko commented Feb 3, 2023

Probably related because styleLayerExists is called on the second instance of the map which is at the time of calling already disposed.

@irjayjay
Copy link

This doesn't seem to be fixed.
Map 1 initialises without issues.
Map 2 initialises, then we destroy it later.
Back on map1, any methods run on its MapboxMap instance throws:
PlatformException(channel-error, Unable to establish connection on channel., null, null)

Seems the second map's instance is somehow bound to the first map's MapboxMap instance now.

Miraculously the first map is still able to function despite these exceptions. So it's as if it's bound to two maps at the same time.

@irjayjay
Copy link

Just an update on our issue. We have a home screen with a map and I noticed the whole map widget rebuilds each time we pop the navigation stack back home.
Since it was rebuilding and we often move the map based on actions done on child pages, it was trying to run these methods on an old instance of the map controller.

This is unfortunate, that the map is rebuilt entirely.

We made a hack where we save a reference to the map widget the first time it's built, then return this map variable each time the build is retriggered, instead of allowing it to rebuild each time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants