为什么setState在一段时间后停止工作?

时间:2018-09-13 12:09:10

标签: stream dart flutter setstate

在每个StateFull小部件正在监听其initState函数中的Stream的那一刻,我正在开发一个应用程序。然后,从Stream接收的数据将在小部件状态下更新。

问题是,在1分钟或更短的时间内,图形界面不再更新。但是,该流仍在接收数据,我可以通过在侦听功能中放置一个打印功能来辨别。

请注意,该流来自StreamController().stream.asBroadcastStream(),因为我需要从多个窗口小部件收听相同的流。如果有帮助,Here是我正在接收的数据及其时间的API。每个数据包都在自己的流中。

编辑:例如,

DeltaInfo类扩展了StatefulWidget {   DeltaInfoState createState()=> DeltaInfoState(); }

class DeltaInfoState extends State<DeltaInfo> {

  LapData playerCarLapData;
  LapData carBehindLapData;
  LapData carInFrontLapData;

  int carInFrontIndex;
  int carBehindIndex;
  int numberOfRacers = 20;
  int session = SessionStatus.raceOne;

  @override initState(){
    super.initState();
    sessionStream.asBroadcastStream().listen((PacketSessionInfo packet){
      session = packet.sessionType;
      sessionStream.drain();
    });

    lapDataStream.asBroadcastStream().listen((PacketLapData packet){
      if(SessionStatus.isRace(sessionType: session)){
        numberOfRacers = 0;
        playerCarLapData = packet.lapData[packet.headder.playerCarIndex];
        int i = 0;
        carInFrontLapData = null;
        carBehindLapData = null;
        carInFrontIndex = null;
        carBehindIndex = null;

        packet.lapData.forEach((LapData car){
          if(car == null) return;
          if(ResultStatus.isInRace(resultStatus: car.resultStatus)){
            this.numberOfRacers++;
          }
          if(car.carPosistion == playerCarLapData.carPosistion - 1){
            carInFrontIndex = i;
            carInFrontLapData = car;
          }
          if(car.carPosistion == playerCarLapData.carPosistion + 1) {
            carBehindIndex = i;
            carBehindLapData = car;
          }
          i++;
        });
        carTelemtryStream.asBroadcastStream().listen((PacketCarTelemtryData packet){
          CarTelemtryData playersCar = packet.carTelemtryData[packet.headder.playerCarIndex];
          if(carInFrontIndex != null){
            CarTelemtryData carInFront = packet.carTelemtryData[carInFrontIndex];
            double time = calculateDelta(
                carALapData: carInFrontLapData,
                carBLapData: playerCarLapData,
                carATelemtry: carInFront,
                carBTelemtry: playersCar,
                carAInfront: true
              );
            setState((){
              inFrontValue = "+ ${time.toStringAsFixed(3)}";
            });
          } else {
            setState((){
              inFrontValue = "In lead";
            });
          }

          if(carBehindIndex != null){
            CarTelemtryData carBehind = packet.carTelemtryData[carBehindIndex];
            setState((){
            double time = calculateDelta(
                carALapData: carBehindLapData,
                carBLapData: playerCarLapData,
                carATelemtry: carBehind,
                carBTelemtry: playersCar,
                carAInfront: false
              );
              behindValue = "- ${time.toStringAsFixed(3)}";
            });
          } else {
            setState((){
              behindValue = "Last Place";
            });
          }
        });
      } else {
        LapData player = packet.lapData[packet.headder.playerCarIndex];

        Map<String, int> currentTime = timeInfoFromSeconds(player.currentLapTime);
        int mins = currentTime["mins"];
        String seconds = currentTime["seconds"].toString().padLeft(2, '0');
        // String ms = (player.currentLapTime % 1).toString().substring(2, 5);
        String ms = "000";
        setState((){
          inFrontValue = "$mins:$seconds.$ms";
        });

        Map<String, int> bestTime = timeInfoFromSeconds(player.bestLapTime);
        mins = bestTime["mins"];
        seconds = bestTime["seconds"].toString().padLeft(2, '0');
        ms = (player.bestLapTime % 1).toString().substring(2, 5);
        setState((){
          behindValue = "$mins:$seconds.$ms";
        });
      }
      lapDataStream.drain();
    });
  }
  String inFrontValue = "A";
  String behindValue = "A";

  @override Widget build(BuildContext context){
    return Expanded(
      child: Column(
        children: [
          Expanded(
            child: FittedBox(
              child: Text("$inFrontValue"),
            ),
          ),
          Expanded(
            child: FittedBox(
              child: Text("$behindValue"),
            ),
          ),
        ]
      )
    );
  }
}


double calculateDelta(
  {@required LapData carALapData,
  @required LapData carBLapData,
  @required CarTelemtryData carATelemtry,
  @required CarTelemtryData carBTelemtry,
  @required bool carAInfront}
){
    if(carAInfront){
      double distanceDifference = carALapData.totalDistance - carBLapData.totalDistance;
      double carBSpeed = kphToMs(carBTelemtry.speed);
      return distanceDifference/carBSpeed;
    } else {
      double distanceDifference = carBLapData.totalDistance - carALapData.totalDistance;
      double carASpeed = kphToMs(carATelemtry.speed);
      return distanceDifference/carASpeed;
    }
}



double kphToMs(int kph){
  return kph*0.2777778;
}

然后将流定义为以下内容

StreamController<PacketLapData> _lapDataStream = StreamController<PacketLapData>();
Stream<PacketLapData> lapDataStream = _lapDataStream.stream.asBroadcastStream();

1 个答案:

答案 0 :(得分:0)

最后,我没有在initState上侦听流,而是在构建函数中使用了StreamBuilder。这表明已经停止了滞后/冻结。