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

Flutter程序抛出NotInitializedError问题排查求助

Flutter程序抛出NotInitializedError异常排查

开发的Flutter程序无法正常运行,抛出Instance of 'NotInitializedError'异常。原本推测问题出在getLocation()方法或SharedPreferences变量上,通过打印日志发现代码执行卡在loc.LocationData _locationData = await _location.getLocation();这一行。

问题代码

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart' as lat;
import 'package:location/location.dart' as loc;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:mapbox_gl/mapbox_gl.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';

//besafe

 late SharedPreferences sharedPreferences;
LatLng getCurrentLatLngFromSharedPrefs() {
  return   LatLng(sharedPreferences.getDouble('latitude')!,
      sharedPreferences.getDouble('longitude')!);
}
void main() async{

  runApp(const MyApp());
  sharedPreferences =await SharedPreferences.getInstance();
  const color2= Color(0xfb74093);
}

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 MaterialApp(
      title: 'BeSafe',
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: const MyHomePage(title: 'BeSafe'),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

   late CameraPosition _initialCameraPosition;
   late MapboxMapController controller;


  static const List<String> imageList = [
    "https://www.uber-assets.com/image/upload/f_auto,q_auto:eco,c_fill,w_1099,h_733/v1568070387/assets/b5/0a5191-836e-42bf-ad5d-6cb3100ec425/original/UberX.png",
    "https://www.uber-assets.com/image/upload/f_auto,q_auto:eco,c_fill,w_956,h_537/v1569012661/assets/19/dea9bc-88d6-461e-a233-17ed4d8cdc09/original/Taxi.png",
    "https://www.uber-assets.com/image/upload/f_auto,q_auto:eco,c_fill,w_956,h_537/v1571927853/assets/39/c1c2c7-61eb-4432-9bac-728b974207e7/original/cityscoot-icon-mobile.png"
  ];
   void initState(){
     super.initState();
     initializeLocationandSave();
     LatLng latlng= getCurrentLatLngFromSharedPrefs();
    _initialCameraPosition=CameraPosition(target:latlng  ,zoom:15);
    print("he");

   }
  void initializeLocationandSave() async{
    sharedPreferences = await SharedPreferences.getInstance();

    loc.Location _location = loc.Location();
    bool? _serviceEnabled;
    loc.PermissionStatus? _permissionGranted;

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

    _permissionGranted = await _location.hasPermission();
    if (_permissionGranted == loc.PermissionStatus.denied) {
      _permissionGranted = await _location.requestPermission();
    }
    print("yo");
    loc.LocationData _locationData = await _location.getLocation();    print("bye");
    sharedPreferences.setDouble('latitude',_locationData.latitude!);
    sharedPreferences.setDouble('longitude',_locationData.latitude!);
    LatLng currentlatlng= getCurrentLatLngFromSharedPrefs();
  }
  _onMapCreated(MapboxMapController controller) async {
    this.controller=controller;

  }
   _onStyleLoadedCallback() async{

   }

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      backgroundColor: Colors.white,
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Stack(
        children: <Widget>[
              MapboxMap(
                accessToken: dotenv.env['MAPBOX_ACCESS_TOKEN'] ,initialCameraPosition: _initialCameraPosition,
                onMapCreated: _onMapCreated,
                onStyleLoadedCallback: _onStyleLoadedCallback,
                myLocationEnabled: true,
                myLocationTrackingMode: MyLocationTrackingMode.TrackingGPS,
                minMaxZoomPreference: const MinMaxZoomPreference(14, 17),
              ),
    new Positioned(
    child:SizedBox(
    height: 60,
    ),),
    new Positioned(
      child:
      Padding(
        padding:EdgeInsets.only(left:30,right:30,top:30),
        child:
        SizedBox(
            height: 40,
            child: TextField(
              decoration: InputDecoration(
                contentPadding: const EdgeInsets.all(30.0),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(50.0),
                  borderSide: BorderSide(
                      width: 10),
                ),
                fillColor: Colors.white24,
                filled: true,

              ),

            ))

      ),
    ),

          Padding(
            padding:EdgeInsets.only(top: 556),
            child: CarouselSlider(

              options: CarouselOptions(
                enlargeCenterPage: true,
                enableInfiniteScroll: true,
                height: 200,
                autoPlay: true,
              ),
              items: imageList.map((e) => ClipRRect(
                borderRadius: BorderRadius.circular(8),
                child: Stack(
                  fit: StackFit.expand,
                  children: <Widget>[
                    Image.network(e,
                      width: 1050,
                      height: 300,
                      fit: BoxFit.cover,)
                  ],
                ) ,
              )).toList(),

            ),
          ),



        ] ,


      ),
    );
  }
}

错误栈信息

The following NotInitializedError was thrown building MyHomePage(dirty, state: _MyHomePageState#9417a):
Instance of 'NotInitializedError'

The relevant error-causing widget was: 
  MyHomePage MyHomePage:file:///C:/Users/ali33/StudioProjects/besafe/lib/main.dart:35:19
When the exception was thrown, this was the stack: 
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49  throw_
packages/flutter_dotenv/src/dotenv.dart 42:7                                                                               get env
packages/besafe/main.dart 113:40                                                                                           build
packages/flutter/src/widgets/framework.dart 4919:27                                                                        build
packages/flutter/src/widgets/framework.dart 4806:15                                                                        performRebuild
packages/flutter/src/widgets/framework.dart 4977:11                                                                        performRebuild
packages/flutter/src/widgets/framework.dart 4529:5                                                                         rebuild

问题分析与修复方案

1. 首要解决:NotInitializedError异常

从错误栈可以明确看到,异常来自flutter_dotenv的env未初始化。当前代码在main函数中直接先调用runApp,但没有先加载dotenv配置,导致MapboxMap组件在构建时访问dotenv.env['MAPBOX_ACCESS_TOKEN']时抛出未初始化异常。

修复方法:
在main函数中先初始化Flutter绑定,再加载dotenv配置,最后执行runApp和其他异步操作:

void main() async{
  WidgetsFlutterBinding.ensureInitialized(); // 必须先初始化Flutter绑定
  await dotenv.load(fileName: ".env"); // 加载.env文件,确保路径与项目中文件一致
  sharedPreferences = await SharedPreferences.getInstance();
  runApp(const MyApp());
  const color2= Color(0xfb74093);
}

2. 解决SharedPreferences空指针风险

当前initState中直接调用getCurrentLatLngFromSharedPrefs(),但此时initializeLocationandSave()是异步方法,SharedPreferences中还没有保存经纬度数据,或者全局变量sharedPreferences可能未完成初始化,会导致空指针异常。

修复方法:

  • 在获取SharedPreferences中的经纬度时添加空值判断,提供默认坐标兜底:
LatLng getCurrentLatLngFromSharedPrefs() {
  double? lat = sharedPreferences.getDouble('latitude');
  double? lng = sharedPreferences.getDouble('longitude');
  return LatLng(lat ?? 37.7749, lng ?? -122.4194); // 替换为合适的默认坐标
}
  • 在initializeLocationandSave获取到定位后,更新UI的相机位置:
void initializeLocationandSave() async{
  sharedPreferences = await SharedPreferences.getInstance();

  loc.Location _location = loc.Location();
  bool? _serviceEnabled;
  loc.PermissionStatus? _permissionGranted;

  _serviceEnabled = await _location.serviceEnabled();
  if (!_serviceEnabled) {
    _serviceEnabled = await _location.requestService();
    if (!_serviceEnabled) {
      // 用户拒绝开启定位服务,可添加弹窗提示
      return;
    }
  }

  _permissionGranted = await _location.hasPermission();
  if (_permissionGranted == loc.PermissionStatus.denied) {
    _permissionGranted = await _location.requestPermission();
    if (_permissionGranted != loc.PermissionStatus.granted) {
      // 用户拒绝定位权限,可添加弹窗提示
      return;
    }
  }
  print("yo");
  try {
    loc.LocationData _locationData = await _location.getLocation();    
    print("bye");
    sharedPreferences.setDouble('latitude',_locationData.latitude!);
    sharedPreferences.setDouble('longitude',_locationData.longitude!); // 修复此处错误:之前错误将latitude赋值给longitude
    setState(() {
      _initialCameraPosition = CameraPosition(
        target: LatLng(_locationData.latitude!, _locationData.longitude!),
        zoom:15
      );
    });
  } catch(e) {
    print("获取定位失败:$e");
  }
}

3. 修复定位获取卡住的问题

定位卡在getLocation()通常有以下原因,对应修复方案:

  • 定位权限未正确授予:上述代码已添加权限检查和用户拒绝后的处理逻辑
  • 设备定位服务未开启:代码中已处理请求开启服务的逻辑
  • 平台配置缺失:
    • Android:在AndroidManifest.xml中添加定位权限:
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
      
    • iOS:在Info.plist中添加定位权限描述:
      <key>NSLocationWhenInUseUsageDescription</key>
      <string>需要获取您的位置信息以展示地图</string>
      

内容的提问来源于stack exchange,提问作者Ali Fakhreldin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:40:33