I am generating a list of a thousand items from an api response, this would hang my main thread so I seperated this task to five seperate isolates using the compute() method, where each isolate generates a part of the list,each containing 200 items. I create all these isolates using a sixth isolate which combines all the lists and returns them to the main thread where it's being loaded.
Everything works fine except that the main thread still hangs for a bit, the refresh indicator on my list-view still hangs for the first 15 seconds or so...
List<CoinData> fetchCoinList(ListConfig listConfig){
List<CoinData> coinList = [];
for(int index = listConfig.listStart; index < listConfig.listEnd; index++){
print("In Isolate with range ${listConfig.listStart} - ${listConfig.listEnd} ");
if(jsonDecode(listConfig.listData)['data'][index]['rank'] == null||
jsonDecode(listConfig.listData)['data'][index]['priceUsd'] == null ||
jsonDecode(listConfig.listData)['data'][index]['changePercent24Hr'] ==null)
continue;
int rank = int.parse(jsonDecode(listConfig.listData)['data'][index]['rank']);
String name = jsonDecode(listConfig.listData)['data'][index]['name'];
String symbol = jsonDecode(listConfig.listData)['data'][index]['symbol'];
String id = jsonDecode(listConfig.listData)['data'][index]['id']??"";
double value =
double.parse(jsonDecode(listConfig.listData)['data'][index]['priceUsd']);
double percentChange = double.parse(
jsonDecode(listConfig.listData)['data'][index]['changePercent24Hr']);
String image =
'https://static.coincap.io/assets/icons/${symbol
.toLowerCase()}@2x.png';
coinList.add(CoinData(rank, id, name, symbol, value, percentChange, image));
}
return coinList;
}
Future <List<CoinData>> generateList(String response) async {
List<CoinData> coinList;
print("Inside isolate");
ListConfig listConfig1 = ListConfig(response, 0, 200);
ListConfig listConfig2 = ListConfig(response, 200, 400);
ListConfig listConfig3 = ListConfig(response, 400, 600);
ListConfig listConfig4 = ListConfig(response, 600, 800);
ListConfig listConfig5 = ListConfig(response, 800, 1000);
//creating 5 isolates and waiting for their execution
var results = await Future.wait([
compute(fetchCoinList,listConfig1),compute(fetchCoinList,listConfig2),compute(fetchCoinList,listConfig3),compute(fetchCoinList,listConfig4),compute(fetchCoinList,listConfig5)
]);
coinList = results[0] + results[1] + results[2] +results[3] + results[4];
return coinList;
}
The isolate is being called in the main thread using this function...
Future<void> fetchData() async {
setState(() {
loading = true;//unrelated to the refreshindicator widget
});
for (int i = 0; i < 3; i++) {
await widget.mynetwork.startNetwork();
if (widget.mynetwork.cryptoData.isNotEmpty) break;
print('Restarting Network...');
}
if(widget.mynetwork.cryptoData.isNotEmpty){
print("creating list");
widget.cryptoList = await compute(generateList,widget.mynetwork.cryptoData);
}
setState(() {
loading = false;
});
}
widget where the function is being triggered
RefreshIndicator(
onRefresh: fetchData,
child: ListView.separated(
physics: BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return filteredList.isNotEmpty ? CoinTile(
filteredList[index]
):CoinTile(
widget.cryptoList[index]
);
},
itemCount: filteredList.isEmpty ? widget.cryptoList.length : filteredList.length,
separatorBuilder: (context, index) {
return Divider(
height: 1,
thickness: 1,
color: Colors.grey.shade100,
);
},
),
),