Flutter报错LateInitializationError: currentPosition未初始化如何解决?
错误成因
late关键字修饰的变量意味着你承诺会在首次访问它之前完成赋值,且该变量不可为空。你在build方法中直接执行currentposition != null判空操作时,此时还没触发Locate me按钮点击、或者定位异步方法还未执行完赋值操作,相当于提前访问了未初始化的late变量,哪怕只是判空也会直接抛出LateInitializationError。- 额外补充:你的权限校验逻辑存在漏洞,当定位服务未开启、权限被拒绝时,代码只会弹出Toast,依旧会向下执行获取定位的逻辑,极端情况下也会导致
currentposition赋值失败。
修复方案
- 移除
currentposition的late修饰符,改为可空类型声明,默认初始值为null,此时判空操作就不会触发未初始化错误:
// 替换原有的 late Position currentposition; Position? currentposition;
- 完善权限校验逻辑,异常情况下直接终止方法执行,避免后续无效逻辑报错:
import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:geocoding/geocoding.dart'; import 'package:geolocator/geolocator.dart'; class Home extends StatefulWidget { @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { String currentAddress = '我的地址'; Position? currentposition ; Future<Position?> _determinePosition() async { bool serviceEnabled; LocationPermission permission; serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { Fluttertoast.showToast(msg: '请开启定位服务'); return null; } permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { Fluttertoast.showToast(msg: '定位权限被拒绝'); return null; } } if (permission == LocationPermission.deniedForever) { Fluttertoast.showToast( msg: '定位权限被永久拒绝,无法申请权限'); return null; } Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high); try { List<Placemark> placemarks = await placemarkFromCoordinates(position.latitude, position.longitude); Placemark place = placemarks[0]; setState(() { currentposition = position; currentAddress = "${place.locality}, ${place.subLocality},${place.street}, ${place.postalCode}"; }); } catch (e) { print(e); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('我的定位'), ), body: Center( child: Column( children: [ Text(currentAddress), currentposition != null ? Text('纬度 = ' + currentposition!.latitude.toString()) : Container(), currentposition != null ? Text('经度 = ' + currentposition!.longitude.toString()) : Container(), TextButton( onPressed: () { _determinePosition(); }, child: Text('获取我的位置')) ], ),), ); } }
- 可空类型变量访问时添加
!非空断言即可,原有UI显示逻辑无需大幅调整。
内容的提问来源于stack exchange,提问作者Shubham_Kr
相关产品推荐
相关产品推荐

