【问题标题】:FLUTTER: Why am I getting thiss error? 'microsecondsSinceEpoch'颤振:为什么我会收到这个错误? '自纪元以来的微秒'
【发布时间】:2020-09-12 14:59:58
【问题描述】:

我正在尝试构建一个天气应用程序。我正在从 Openweather 地图中获取天气数据。正如您将在最后一种方法中看到的那样,我使用“fromMillisecondsSinceEpoch”将我从 Openweather 地图获得的 Unix 时间戳转换为时间和日期。 Unix 时间戳代表日出和日落。

问题是当我关闭应用程序或热重启或热重新加载应用程序时,我收到一个错误(我在下面提供了错误)。然后当我再次热重载应用程序时,它开始正常工作,热重载是让它再次工作的唯一方法。

我没有使用“fromMicrosecondsSinceEpoch”,因为这会将 Unix 时间戳转换为时间和日期,但那个时间和日期是 50 年前。

代码:

import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'GetLocation.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

void main() {
  runApp(AuraWeather());
}

class AuraWeather extends StatefulWidget {
  @override
  _AuraWeatherState createState() => _AuraWeatherState();
}

class _AuraWeatherState extends State<AuraWeather> {
  var apiKey = '5f10958d807d5c7e333ec2e54c4a5b16';
  var weatherIcon;
  var description;
  var maxTemp;
  var minTemp;
  var format_sunRise;
  var sunRise;
  var format_sunSet;
  var format_sunRiseEnd;
  var format_sunSetEnd;
  var sunSet;
  var temp;
  var city;
  var dataDecoded;
  var latitude;
  var longitude;

  @override
  Widget build(BuildContext context) {
    setState(() {
      getLocation();
    });

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage(displayBackground()),
          ),
        ),
        child: BackdropFilter(
          filter: ImageFilter.blur(sigmaY: 2, sigmaX: 2),
          child: Container(
            color: Colors.black.withOpacity(0.5),
            child: Scaffold(
              backgroundColor: Colors.transparent,
              body: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Column(
                    children: <Widget>[
                      Container(
                        child: Center(
                          child: Text(
                            '$city',
                            style: TextStyle(
                              fontSize: 25,
                              color: Colors.white,
                              fontFamily: 'Roboto',
                            ),
                          ),
                        ),
                      ),
                      Container(
                        child: Icon(
                          FontAwesomeIcons.locationArrow,
                          color: Colors.white,
                        ),
                      ),
                      Container(
                        margin: EdgeInsets.only(top: 80),
                        child: Text(
                          '$temp' + '°',
                          style: TextStyle(
                              fontSize: 50,
                              color: Colors.white,
                              fontWeight: FontWeight.w600),
                        ),
                      ),
                    ],
                  ),
                  Container(
                    margin: EdgeInsets.only(top: 20),
                    child: Icon(
                      getWeatherIcon(),
                      size: 100,
                      color: Colors.white,
                    ),
                  ),
                  Container(
                    child: Center(
                      child: Text(
                        '$maxTemp ° | $minTemp °',
                        style: TextStyle(fontSize: 20, color: Colors.white),
                      ),
                    ),
                  ),
                  Container(
                    child: Text(
                      '$description',
                      style: TextStyle(
                        fontSize: 20,
                        color: Colors.white,
                        fontFamily: 'Roboto mono',
                      ),
                    ),
                  ),
                  Container(
                    child: FlatButton(
                      child: Icon(
                        Icons.refresh,
                        color: Colors.white,
                        size: 40,
                      ),
                      color: Colors.transparent,
                      onPressed: () {
                        setState(
                          () {
                            getLocation();
                          },
                        );
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  // display background images based on current time
  displayBackground() {
    var now = DateTime.now();
    var currentTime = DateFormat.jm().format(now);

    DateFormat midNight = new DateFormat.Hm();
    DateTime midNightTime = midNight.parse("10:30");
    midNightTime = new DateTime(
        now.year, now.month, now.day, midNightTime.hour, midNightTime.minute);

    if (currentTime.contains('AM')) {
      return 'images/Blood.png';
    } else if (currentTime.contains('PM')) {
      return 'images/sunSet.jpg';
    }

    /*if (now.isBefore(format_sunRise)){
      return 'images/night.jpg';
    }else if(now.isAfter(format_sunRise) && (now.isBefore(format_sunRiseEnd))){
      return 'images/sunRise.jpg';
    }else if((format_sunRiseEnd) && (now.isBefore(format_sunSet))){
      return 'images/day.jpg';
    }else if((now.isAfter(format_sunSet)) && (now.isBefore(format_sunRiseEnd))){
      return 'images/sunSet.jpg';
    }else if((now.isAfter(format_sunRiseEnd)) && (now.isBefore(midNightTime))){
      return 'images/night.jpg';
    }*/
  }

  getWeatherIcon() {
    var now = DateTime.now();
    var currentTime = DateFormat.jm().format(now);

    DateFormat midNight = new DateFormat.Hm();
    DateTime midNightTime = midNight.parse("23:59");
    midNightTime = new DateTime(
        now.year, now.month, now.day, midNightTime.hour, midNightTime.minute);

    if (now.isBefore(format_sunRise)) {
      return FontAwesomeIcons.moon;
    } else if (now.isAfter(format_sunRise) &&
        (now.isBefore(format_sunRiseEnd))) {
      return FontAwesomeIcons.solidSun;
    } else if ((format_sunRiseEnd) && (now.isBefore(format_sunSet))) {
      return FontAwesomeIcons.cloudRain;
    } else if ((now.isAfter(format_sunSet)) &&
        (now.isBefore(format_sunRiseEnd))) {
      return FontAwesomeIcons.snowflake;
    } else if ((now.isAfter(format_sunRiseEnd)) &&
        (now.isBefore(midNightTime))) {
      return FontAwesomeIcons.cloudMoonRain;
    }
  }

  //getLocation
  void getLocation() async {
    Getlocation getlocation = Getlocation();
    await getlocation.getCurrentLocation();

    latitude = getlocation.latitude;
    print(latitude);
    longitude = getlocation.longitude;
    print(longitude);
    print(getlocation.city);
    city = getlocation.city;
    getTemp(getlocation.latitude, getlocation.longitude);
  }

  //Get current temp
  Future<void> getTemp(double lat, double lon) async {
    http.Response response = await http.get(
        'https://api.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&appid=$apiKey&units=metric');

    //print(response.body);

    dataDecoded = jsonDecode(response.body);

    description = dataDecoded['weather'][0]['description'];

    temp = dataDecoded['main']['temp'].toInt();
    maxTemp = dataDecoded['main']['temp_max'].toInt();
    minTemp = dataDecoded['main']['temp_min'].toInt();

    sunRise = dataDecoded['sys']['sunrise'];
    format_sunRise = DateTime.fromMillisecondsSinceEpoch(sunRise * 1000);
    format_sunRiseEnd = format_sunRise.add(Duration(hours: 1));

    sunSet = dataDecoded['sys']['sunset'];
    format_sunSet = DateTime.fromMillisecondsSinceEpoch(sunSet * 1000);
    format_sunSetEnd = format_sunSet.add(Duration(hours: 1));

    print('Current temp: $temp');
    print('Max temp: $maxTemp');
    print('Min temp: $minTemp');
    print('Sunrise time: $format_sunRise');
    print('Sunset time: $format_sunSet');
  }
}

我遇到的错误:

Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building AuraWeather(dirty, state: _AuraWeatherState#59e2b):
The getter 'microsecondsSinceEpoch' was called on null.
Receiver: null
Tried calling: microsecondsSinceEpoch

The relevant error-causing widget was: 
  AuraWeather file:///C:/Users/aldo0/Desktop/Learn_Flutter/aura_weather/lib/main.dart:12:10
When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      DateTime.isBefore (dart:core-patch/date_patch.dart:84:51)
#2      _AuraWeatherState.getWeatherIcon (package:com/main.dart:183:13)
#3      _AuraWeatherState.build (package:com/main.dart:96:23)
#4      StatefulElement.build (package:flutter/src/widgets/framework.dart:4619:28)

就像我上面所说的,当我热重载应用程序时,它会再次运行。然后当我再次热重新加载它时,我再次收到此错误。很烦人 应用程序目前无法在物理设备上使用,因为它启动时出现红色错误屏幕,显示“getter 'microsecondsSinceEpoch' was called on null。”

感谢您的帮助。

【问题讨论】:

    标签: flutter exception dart time


    【解决方案1】:

    好吧,看来

    getWeatherIcon 在执行buildformat_sunRise 为空时首先被调用,但代码仍在运行,因此它执行getLocation 然后getTemp 这就是为什么在HotReload 之后format_sunRise 不是空...

    解决方案..

    你可以验证getTemp 何时被执行...所以在build 中你可以添加一些条件来知道要绘制什么

    或者您可以使用FutureBuilder

    https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

    【讨论】:

    • 我曾尝试在getLocation 之后调用getTemp 方法以在调用getWeatherIcon 之前获取数据,但我仍然遇到同样的错误。
    • 但问题是它build比调用api快,调用api并没有阻塞线程,所以它会尝试执行build并且有空值...如果你不想添加条件或使用FutureBuilder,可以尝试初始化变量
    【解决方案2】:

    我有同样的错误。我查看了@jjchiw 的答案和评论(...你可以尝试初始化变量),它对我有用。我认为你应该在initState 中调用getLocation 方法,而不是在build 下的setState 中调用

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      相关资源
      最近更新 更多