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

无法为可空变量userCurrentPosition赋值,触发空检查错误求助

问题:SharedPreferences读取的经纬度无法赋值给userCurrentPosition

需求:若变量lat已有值,则避免调用locateUserPosition()函数。由于该值存储在SharedPreferences中,使用Timer预留读取时间。

当前问题:从SharedPreferences读取的lat和lng已有值,但执行userCurrentPosition?.latitude = lat!;和userCurrentPosition?.longitude = lng!;后,userCurrentPosition仍为null,打印时触发_CastError (Null check operator used on a null value)错误。

代码片段:

initState() {
  super.initState();
  dataFuture = getData();

  if (lat == null) {
    Timer(Duration(seconds: 1), () {
      if (lat == null) {
        print('location is null');
        locateUserPosition();
      } else {
        userCurrentPosition?.latitude = lat!;
        userCurrentPosition?.longitude = lng!; 

        // After running the two above lines, where lat and lng both have values,
        // they still couldn't be assigned to the userCurrentPosition.latitude and 
        // userCurrentPosition.longitude. The next line shows this error
        // _CastError (Null check operator used on a null value)

        print('usercurrentposition: ${userCurrentPosition!.latitude}'); // <- error here
      }
    });

    // EasyLoading.showSuccess('Use in initState');
    // debugPrint("radius: $radius");
  } else {
    userCurrentPosition?.latitude = lat!;
    userCurrentPosition?.longitude = lng!;
    // EasyLoading.showSuccess('Use in initState');
    // debugPrint("radius: $radius");
  }
  // setState(() {});
}

编辑补充:运行时lat和lng均有值,但赋值后userCurrentPosition的latitude和longitude仍为null,打印时抛出上述错误。


问题原因与解决方案

核心原因

userCurrentPosition初始值为null,你使用了?.操作符赋值属性——这个操作符的规则是如果对象为null,直接跳过后续代码执行。所以你写的userCurrentPosition?.latitude = lat!;根本没有执行,userCurrentPosition始终是null,最后用!强制解包null自然触发空指针错误。

解决方案

  1. 先初始化userCurrentPosition对象
    不要试图给null对象的属性赋值,直接创建实例并传入经纬度:

    // 假设userCurrentPosition是LatLng类型,直接初始化
    userCurrentPosition = LatLng(lat!, lng!);
    

    代替原来的分步属性赋值操作。

  2. 抛弃Timer,改用异步读取SharedPreferences
    Timer等待1秒的方式完全不可靠(读取耗时不确定),正确的做法是在initState中调用异步函数读取SharedPreferences:

    @override
    void initState() {
      super.initState();
      dataFuture = getData();
      // 调用异步读取方法
      _loadSavedLocation();
    }
    
    void _loadSavedLocation() async {
      // 读取SharedPreferences的逻辑
      final prefs = await SharedPreferences.getInstance();
      lat = prefs.getDouble('lat');
      lng = prefs.getDouble('lng');
    
      if (lat == null || lng == null) {
        locateUserPosition();
      } else {
        // 初始化userCurrentPosition
        userCurrentPosition = LatLng(lat!, lng!);
        print('usercurrentposition: ${userCurrentPosition!.latitude}');
        // 如果需要更新UI,调用setState
        setState(() {});
      }
    }
    

额外说明

  • 如果你需要在UI中使用userCurrentPosition,记得在赋值后调用setState(() {})触发组件重建。
  • 永远不要依赖Timer处理异步操作,异步场景下await才是可靠的等待方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:25:06