在 flutter 中使用计算从 json 文件中读取大数据

Using compute to read large data from json file in flutter

我正在尝试从 JSON 文件中读取大量数据。数据检索导致卡顿,所以我决定使用 compute 但后来 return 没有任何结果。

这是我的 compute 代码,没有 return 数据:

Future<List<City>> getCityList (BuildContext context) async{

    final response = await DefaultAssetBundle.of(context).loadString('Assets/citylist.json');
    final decoded = await compute(json.decode, response);
    return decoded.map<City>((json) => fromJson(json)).toList();
  }

这是我没有计算的代码,它执行 returns 数据但导致卡顿:

Future<List<City>> getCityList (BuildContext context) async{

    final response = await DefaultAssetBundle.of(context).loadString('Assets/citylist.json');
    final decoded = json.decode(response);
    return decoded.map<City>((json) => fromJson(json)).toList();
  }

这是我的 Futurebuilder 的代码:

FutureBuilder(
        future:  getCityList(context),
        builder: (context, snapshot) {
            if (snapshot.hasData){
              return ListView.builder(
                  itemCount: snapshot.data?.length ?? 0,
                  itemBuilder: (BuildContext context, int index) {
                    return FlatButton(
                      onPressed: (){

                      },
                      child: Container(
                        child: Text(snapshot.data[index].name, style: TextStyle(fontSize: 20.0, color: Theme.of(context).accentColor),),
                        padding: const EdgeInsets.all(15.0),
                      ),
                    );
                  }
              );
            }
            return Center(child: CircularProgressIndicator(),);
          })

您不能传递对象方法(或闭包)- 相反,您需要路径顶级函数。

应该是await compute(jsonDecode, response) 其中 jsonDecode 是来自 json.dart 的顶级函数。(只需使用 jsonDecode func 而不是 json.decode

此外,我建议创建一个像 decodeCities 这样的方法,您可以在其中解码和映射您的 JSON。 在这里你可以找到一个样本和更多细节

已更新:

接下来我使用的测试 JSON(12mb) https://raw.githubusercontent.com/lutangar/cities.json/master/cities.json

final decoded = await compute(decode, response);
print(decoded.length);

List<City> decode(dynamic obj) {
  final decoded = jsonDecode(obj);
  return decoded.map<City>((json) => City.fromJson(json)).toList();
}

class City {
  String country;
  String name;
  String lat;
  String lng;

  City({this.country, this.name, this.lat, this.lng});

  City.fromJson(Map<String, dynamic> json) {
    country = json['country'];
    name = json['name'];
    lat = json['lat'];
    lng = json['lng'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['country'] = this.country;
    data['name'] = this.name;
    data['lat'] = this.lat;
    data['lng'] = this.lng;
    return data;
  }
}