I am developing an application at the moment where each StateFull widget is listening on a Stream within it's initState function. The data received from the Stream is then updated in the widgets state.
The problem is, after 1min or less, the graphical interface no longer updates. However, the stream is still receiving data, which I can tell by putting a print function in the listen function.
Please note, the stream is from StreamController().stream.asBroadcastStream()
as I need to listen to the same streams from multiple widgets. If it helps, Here is the API to the data I am receiving, along with their timings. Each packet is in it's own stream.
Edit: For example,
class DeltaInfo extends 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;
}
And then the stream is define as the following
StreamController<PacketLapData> _lapDataStream = StreamController<PacketLapData>();
Stream<PacketLapData> lapDataStream = _lapDataStream.stream.asBroadcastStream();
In the end, Instead of listening to the stream on initState, I used a StreamBuilder in the build function instead. This seams to have stopped the lag/freezing.