«Оператор проверки Null, используемый для нулевого значения» при вызове поставщика в dispose()

#flutter #flutter-provider #google-maps-flutter

Вопрос:

У меня есть ошибка «Оператор проверки Null, используемый для нулевого значения» после того, как я покинул страницу Navigator.pop(context) . Стек говорит, что ошибка здесь

 @override
  void dispose() {
    final googleMapsNotifier =
        Provider.of<GoogleMapsNotifier>(context, listen: false); // !!!THIS LINE CAUSES THE ERROR
     googleMapsNotifier.dispose();
    locationSubscription.cancel();
    boundsSubscription.cancel();
    addressSearchController.dispose();
    super.dispose();
  }
 

Вот файл класса, который вызывает этот поставщик

 import 'dart:async';

import 'package:dev/model/mapsModels/geometry.dart';
import 'package:dev/model/mapsModels/location.dart';
import 'package:dev/model/mapsModels/place.dart';
import 'package:dev/model/mapsModels/place_search.dart';
import 'package:dev/services/mapsServices/geolocator_service.dart';
import 'package:dev/services/mapsServices/places_service.dart';
import 'package:dev/services/marker_service.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:rxdart/rxdart.dart';

class GoogleMapsNotifier with ChangeNotifier {
  final geolocatorService = GeolocatorService();
  final placesService = PlacesService();
  final markerService = MarkerService();

  Position? currentLocation;
  List<PlaceSearch> searchResults = [];
  StreamController<Place> selectedLocation = BehaviorSubject<Place>();
  StreamController<LatLngBounds> bounds = BehaviorSubject<LatLngBounds>();
  late Place selectedLocationStatic;
  List<Marker> markers = <Marker>[];

  GoogleMapsNotifier() {
    setCurrentLocation();
  }

  setCurrentLocation() async {
    currentLocation = await geolocatorService.determinePosition();
    selectedLocationStatic = Place(
        geometry: Geometry(
          location: Location(
              lat: currentLocation!.latitude, lng: currentLocation!.longitude),
        ),
        name: '',
        vicinity: '');
    notifyListeners();
  }

  searchPlaces(String searchTerm) async {
    searchResults = await placesService.getAutocomplete(searchTerm);
    notifyListeners();
  }

  setSelectedLocation(String placeId) async {
    var sLocation = await placesService.getPlace(placeId);
    selectedLocation.add(sLocation);
    selectedLocationStatic = sLocation;
    searchResults = [];
    markers = [];
    var newMarker = markerService.createMarkerFromPlace(sLocation);
    markers.add(newMarker);
    var _bounds = markerService.bounds(Set<Marker>.of(markers));
    bounds.add(_bounds as LatLngBounds);
    notifyListeners();
  }

  @override
  void dispose() {
 
      selectedLocation.close();
    

    super.dispose();
  }
}
 

В то же время приложение НЕ давит, и все это прекрасно работает после этой ошибки.
Если я удалю эту строку внутри dispose() , ошибка исчезнет.
Я попробовал это, и это не помогло

Откройте свой терминал и запустите стабильный канал flutter. Затем запустите обновление flutter. После этого запустите восстановление кэша flutter pub, чтобы переустановить пакеты в системном кэше. Затем просто очистите папку сборки с помощью flutter clean.

Врач Флаттера не показывает никаких проблем. Есть какие-нибудь идеи, что это может быть? Заранее спасибо.

UPD: Я обнаружил, что даже если class GoogleMapsNotifier он абсолютно пуст, ошибка остается. Так что это сам вызов

 final googleMapsNotifier = Provider.of<GoogleMapsNotifier>(context, listen: false); 
 

если его расположение внутри dispose() вызывает ошибку.

Ответ №1:

Я решил эту проблему просто. Поскольку поток и его dispose() функция находятся в отдельном классе, доступ к которому осуществляется с помощью поставщика, я вызвал его за пределами dispose() StatefulWidget и поместил его на onTap кнопку, которая открывает контекст.

 onTap: () {
      Provider.of<GoogleMapsNotifier>(context, listen: false).dispose();             
      Navigator.pop(context);
          },
 

Теперь ошибка исчезла.