Flutter 错误:构建 Consumer时抛出 StackOverflowError(脏,依赖项:[_InheritedProviderScope])

发布于 2025-01-14 03:50:33 字数 7716 浏览 0 评论 0原文

我正在尝试使用以下软件包将实时位置跟踪包含到我的应用程序中:


我收到以下错误:

════════ Exception caught by widgets library ═══════════════════════════════════
The following StackOverflowError was thrown building Consumer<LocationProvider>(dirty, dependencies: [_InheritedProviderScope<LocationProvider?>]):
Stack Overflow

The relevant error-causing widget was
Consumer<LocationProvider>
lib/google_map_page.dart:31
When the exception was thrown, this was the stack
#0      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#1      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#2      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#3      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#4      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#5      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#6      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#7      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#8      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#9      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#10     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#11     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#12     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#13     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#14     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#15     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#16     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#17     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#18     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#19     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#20     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#21     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#22     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#23     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#24     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#25     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#26     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
......

package:map_test/提供商/location_provider.dart:55 --> LatLng 获取位置位置 =>地点位置;


有 3 个类:

  1. main.dart
  2. google_map_page.dart
  3. location_provider.dart

1。 main.dart

import 'package:flutter/material.dart';
import 'package:map_test/google_map_page.dart';
import 'package:map_test/provider/location_provider.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => LocationProvider(),
          child: const GoogleMapPage(),
        )
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        home: const GoogleMapPage(),
      ),
    );
  }
}

2. google_map_page.dart

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:map_test/provider/location_provider.dart';
import 'package:provider/provider.dart';

class GoogleMapPage extends StatefulWidget {
  const GoogleMapPage({Key? key}) : super(key: key);

  @override
  State<GoogleMapPage> createState() => _GoogleMapPageState();
}

class _GoogleMapPageState extends State<GoogleMapPage> {
  @override
  void initState() {
    super.initState();
    Provider.of<LocationProvider>(context, listen: false).initalization();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Map2'),
          backgroundColor: Colors.red,
        ),
        body: googleMapUI());
  }

  Widget googleMapUI() {
    return Consumer<LocationProvider>(builder: (consumerContext, model, child) {
      if (model.locationPosition != null) {
        return Column(
          children: [
            Expanded(
              child: GoogleMap(
                mapType: MapType.normal,
                initialCameraPosition:
                    CameraPosition(target: model.locationPosition, zoom: 18),
                myLocationEnabled: true,
                myLocationButtonEnabled: true,
                onMapCreated: (GoogleMapController controller) {},
              ),
            )
          ],
        );
      }
      return Container(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      );
    });
  }
}

3.location_provider.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';

class LocationProvider with ChangeNotifier {
  // Widget loc() {

  //   throw '';
  // }

  bool locationServiceActive = true;

  LocationProvider() {
    Location location;
    location = new Location();
  }
  Location get location => location;

  initalization() async {
    await getUserLocation();
  }

  getUserLocation() async {
    bool _serviceEnabled;
    PermissionStatus _permissionGranted;
    LatLng locationPosition;

    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }
    location.onLocationChanged.listen((LocationData currentLocation) {
      locationPosition = LatLng(
        currentLocation.latitude!,
        currentLocation.longitude!,
      );

      print(locationPosition);
      notifyListeners();
    });
  }

  LatLng get locationPosition => locationPosition; // line 55
}

这是我第一次在 flutter 中编码,由于 Null Safety,我已经遇到了很多问题。问题似乎无穷无尽。 任何建议将不胜感激。

谢谢。

i'm trying to include live location tracking into my app using the following packages:


I am receiving the following error:

════════ Exception caught by widgets library ═══════════════════════════════════
The following StackOverflowError was thrown building Consumer<LocationProvider>(dirty, dependencies: [_InheritedProviderScope<LocationProvider?>]):
Stack Overflow

The relevant error-causing widget was
Consumer<LocationProvider>
lib/google_map_page.dart:31
When the exception was thrown, this was the stack
#0      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#1      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#2      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#3      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#4      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#5      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#6      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#7      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#8      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#9      LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#10     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#11     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#12     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#13     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#14     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#15     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#16     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#17     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#18     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#19     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#20     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#21     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#22     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#23     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#24     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#25     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
#26     LocationProvider.locationPosition
package:map_test/provider/location_provider.dart:55
......

package:map_test/provider/location_provider.dart:55 -->
LatLng get locationPosition => locationPosition;


There is 3 classes:

  1. main.dart
  2. google_map_page.dart
  3. location_provider.dart

1. main.dart

import 'package:flutter/material.dart';
import 'package:map_test/google_map_page.dart';
import 'package:map_test/provider/location_provider.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => LocationProvider(),
          child: const GoogleMapPage(),
        )
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        home: const GoogleMapPage(),
      ),
    );
  }
}

2. google_map_page.dart

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:map_test/provider/location_provider.dart';
import 'package:provider/provider.dart';

class GoogleMapPage extends StatefulWidget {
  const GoogleMapPage({Key? key}) : super(key: key);

  @override
  State<GoogleMapPage> createState() => _GoogleMapPageState();
}

class _GoogleMapPageState extends State<GoogleMapPage> {
  @override
  void initState() {
    super.initState();
    Provider.of<LocationProvider>(context, listen: false).initalization();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Map2'),
          backgroundColor: Colors.red,
        ),
        body: googleMapUI());
  }

  Widget googleMapUI() {
    return Consumer<LocationProvider>(builder: (consumerContext, model, child) {
      if (model.locationPosition != null) {
        return Column(
          children: [
            Expanded(
              child: GoogleMap(
                mapType: MapType.normal,
                initialCameraPosition:
                    CameraPosition(target: model.locationPosition, zoom: 18),
                myLocationEnabled: true,
                myLocationButtonEnabled: true,
                onMapCreated: (GoogleMapController controller) {},
              ),
            )
          ],
        );
      }
      return Container(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      );
    });
  }
}

3.location_provider.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';

class LocationProvider with ChangeNotifier {
  // Widget loc() {

  //   throw '';
  // }

  bool locationServiceActive = true;

  LocationProvider() {
    Location location;
    location = new Location();
  }
  Location get location => location;

  initalization() async {
    await getUserLocation();
  }

  getUserLocation() async {
    bool _serviceEnabled;
    PermissionStatus _permissionGranted;
    LatLng locationPosition;

    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }
    location.onLocationChanged.listen((LocationData currentLocation) {
      locationPosition = LatLng(
        currentLocation.latitude!,
        currentLocation.longitude!,
      );

      print(locationPosition);
      notifyListeners();
    });
  }

  LatLng get locationPosition => locationPosition; // line 55
}

It's my first time coding in flutter, i faced a lot of problem because of the Null Safety already. it just seems like the problems are endless.
any recommendations will be much appreciated.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

围归者 2025-01-21 03:50:34

StackOverflowError 是由自引用引起的,

LatLng get locationPosition => locationPosition;

意味着 locationPosition 是它自己。
因此,建议您通过使用前缀 _ 来修改内部参数变量,

LatLng get locationPosition => _locationPosition;

而您的类参数和构造函数可以像下面这样编写

class LocationProvider with ChangeNotifier {
  LatLng? _locationPosition;
  final Location _location = new Location();

  LocationProvider();

  Location get location => _location;

  LatLng? get locationPosition => _locationPosition;
  // other parts 
}

The StackOverflowError is caused by self reference

LatLng get locationPosition => locationPosition;

means locationPosition is itself.
Hence will suggest you to amend the internal parameter variable by having prefix _

LatLng get locationPosition => _locationPosition;

while your class params and constructor can be written like below

class LocationProvider with ChangeNotifier {
  LatLng? _locationPosition;
  final Location _location = new Location();

  LocationProvider();

  Location get location => _location;

  LatLng? get locationPosition => _locationPosition;
  // other parts 
}
霞映澄塘 2025-01-21 03:50:34

我不确定,但尝试将消费者包装在构建方法中
像这样:

 @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Map2'),
          backgroundColor: Colors.red,
        ),
        body: Consumer<LocationProvider>(builder: (consumerContext, model, child) {
return googleMapUI()});
  }

并添加所需的参数

I am not sure but try to wrap consumer in build method
Like this:

 @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Map2'),
          backgroundColor: Colors.red,
        ),
        body: Consumer<LocationProvider>(builder: (consumerContext, model, child) {
return googleMapUI()});
  }

And add needed parameters

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文