2 years ago

#57268

test-img

Hamza Baig

Flutter - Main thread still hangs even when running heavy computations on seperate isolates

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,
                        );
                      },
                    ),
                  ),

android

multithreading

flutter

dart

dart-isolates

0 Answers

Your Answer

Accepted video resources