在 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;
}
}
我正在尝试从 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;
}
}