You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter应用开启myLocationEnabled时点击返回键崩溃问题求助

Flutter Mapbox 返回键崩溃问题(myLocationEnabled=true时)

你的崩溃核心问题是WillPopScope里的执行顺序错误:你先调用了Navigator.pop(context),这会立即将当前页面从导航栈中移除,页面组件开始销毁,后续的setState根本不会被执行——因为页面已经不存在了。这就导致Mapbox组件在销毁时,myLocationEnabled仍为true,原生层的定位相关资源释放时出现空指针(对应报错里的SEGV_MAPERR,即访问了空内存地址)。

修复步骤

  1. 调整返回逻辑的执行顺序:先更新location状态禁用定位,等待状态更新完成后再执行页面弹出操作。
  2. 在页面销毁时手动清理定位资源:重写dispose方法,确保Mapbox的定位功能在组件销毁前被关闭,避免原生层资源泄漏。

修改后的代码示例

bool location = true;
MapboxMapController? controller;

@override
Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: () async {
      // 先禁用定位,触发组件更新
      setState(() {
        location = false;
      });
      // 等待一帧确保状态更新完成,再弹出页面
      await Future.delayed(const Duration(milliseconds: 100));
      Navigator.pop(context);
      return true;
    },
    child: Scaffold(
      appBar: AppBar(title: const Text('Restaurants Map')),
      body: SafeArea(
        child: Stack(
          children: [
            SizedBox(
              height: MediaQuery.of(context).size.height * 1,
              child: MapboxMap(
                accessToken: dotenv.env['MAPBOX_ACCESS_TOKEN'],
                initialCameraPosition: _initialCameraPosition,
                onMapCreated: _onMapCreated,
                onStyleLoadedCallback: _onStyleLoadedCallback,
                myLocationEnabled: location,
                myLocationTrackingMode: MyLocationTrackingMode.TrackingGPS,
                minMaxZoomPreference: const MinMaxZoomPreference(14, 17),
              ),
            ),
            CarouselSlider(
              items: carouselItems,
              options: CarouselOptions(
                height: 105,
                viewportFraction: 0.6,
                initialPage: 0,
                enableInfiniteScroll: false,
                scrollDirection: Axis.horizontal,
                onPageChanged: (int index, CarouselPageChangedReason reason) {
                  setState(() {
                    pageIndex = index;
                  });
                  _addSourceAndLineLayer(index, true);
                },
              ),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          controller?.animateCamera(
            CameraUpdate.newCameraPosition(_initialCameraPosition),
          );
        },
        child: const Icon(Icons.my_location),
      ),
    ),
  );
}

void _onMapCreated(MapboxMapController mapController) {
  controller = mapController;
}

@override
void dispose() {
  // 页面销毁前强制禁用定位,双重保险
  controller?.setMyLocationEnabled(false);
  super.dispose();
}

额外说明

  • 用Future.delayed等待一帧是为了确保setState触发的组件重建完成,Mapbox已经更新了myLocationEnabled的状态;
  • 在dispose中调用controller.setMyLocationEnabled(false)是直接通过Mapbox控制器操作原生层,避免页面销毁时定位资源未正确释放;

内容的提问来源于stack exchange,提问作者Bart Stencil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:55:23