解析大型 JSON 文件可能会导致应用程序性能不佳和关闭动画。如果解析和计算大型 JSON 文件的时间超过 16 毫秒,用户就会遇到 Jank。 Dart默认使用单线程来执行这些任务,虽然对于较便宜的计算来说简单快速,但在计算量很大时它会失败。
为了避免这些卡顿,可以使用隔离 在后台的不同线程中执行所有计算。在本文中,我们将探索在后台解析 JSON 的过程。为此,请执行以下步骤:
导入http 包。
使用 http 包发出网络请求
将响应更改为列表形式的dart对象
将这项工作移至不同的隔离区
导入 http 包:
要安装 http 包,请在命令提示符中使用以下命令:
或者,如果您使用的是flutter cmd,请使用以下命令:
安装完成后,将依赖添加到 pubsec.yml 文件中,如下所示:
import 'package:http/http.dart' as http;
请求数据:
我们可以使用http.get() 方法 从 JSONPlaceholder REST API 获取 5000 张图像的示例数据,如下所示:
Dart
Future fetchPhotos(http.Client client) async {
return client.get('https://jsonplaceholder.typicode.com/photos');
}
Dart
class Photo_list {
final int photo_id;
final String photo_title;
final String photo_thumbnailUrl;
Photo({this.photo_id, this.photo_title, this.photo_thumbnailUrl});
factory Photo_list.fromJson(Map json) {
return Photo_list(
photo_id: json['id'] as int,
photo_title: json['title'] as String,
photo_thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
Dart
ListPhotos_parser(String responseBody) {
final parsed = json.decode(responseBody).cast>();
return parsed.map((json) => Photo.fromJson(json)).toList();
}
Future> getPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
return Photos_parser(response.body);
}
Dart
Future> getPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
return compute(parsePhotos, response.body);
}
Dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future> getPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
// run Photos_parser in a separate isolate.
return compute(Photos_parser, response.body);
}
List Photos_parser(String responseBody) {
final parsed = jsonDecode(responseBody).cast>();
return parsed.map((json) => Photo.fromJson(json)).toList();
}
class Photo_list{
final int Photo_albumId;
final int Photo_id;
final String Photo_title;
final String Photo_url;
final String Photo_thumbnailUrl;
Photo_list({this.Photo_albumId, this.Photo_id, this.Photo_title, this.Photo_url, this.Photo_thumbnailUrl});
factory Photo_list.fromJson(Map json) {
return Photo_list(
Photo_albumId: json['albumId'] as int,
Photo_id: json['id'] as int,
Photo_title: json['title'] as String,
Photo_url: json['url'] as String,
Photo_thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appTitle = 'Isolate Demo';
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class HomePage extends StatelessWidget {
final String title;
HomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? PhotosList(photos: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
);
}
}
class PhotosList extends StatelessWidget {
final List photos;
PhotosList({Key key, this.photos}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: photos.length,
itemBuilder: (context, index) {
return Image.network(photos[index].Photo_thumbnailUrl);
},
);
}
}
解析和转换数据:
我们现在有 5000 张从http.response 接收到的 JSON 格式的照片,这些照片需要解析并转换为Dart对象列表。要做 show 首先创建一个 Photo 类,如下所示。
在这里,我们将创建一个包含 JSON 数据的 Photo 类,如下所示:
Dart
class Photo_list {
final int photo_id;
final String photo_title;
final String photo_thumbnailUrl;
Photo({this.photo_id, this.photo_title, this.photo_thumbnailUrl});
factory Photo_list.fromJson(Map json) {
return Photo_list(
photo_id: json['id'] as int,
photo_title: json['title'] as String,
photo_thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
现在通过以下步骤更新getPhoto() 函数以返回 Future> :
使用 Photos_parser()函数将响应正文转换为 List。
在 getPhotos()函数中使用 Photos_parser()函数。
Dart
ListPhotos_parser(String responseBody) {
final parsed = json.decode(responseBody).cast>();
return parsed.map((json) => Photo.fromJson(json)).toList();
}
Future> getPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
return Photos_parser(response.body);
}
将工作转移到不同的隔离区:
compute()函数 可用于将工作移动到一个单独的隔离区,在那里它将在后台进行解析和转换。它在后台隔离中运行昂贵的函数并返回结果。
Dart
Future> getPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
return compute(parsePhotos, response.body);
}
完整的源代码:
Dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future> getPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
// run Photos_parser in a separate isolate.
return compute(Photos_parser, response.body);
}
List Photos_parser(String responseBody) {
final parsed = jsonDecode(responseBody).cast>();
return parsed.map((json) => Photo.fromJson(json)).toList();
}
class Photo_list{
final int Photo_albumId;
final int Photo_id;
final String Photo_title;
final String Photo_url;
final String Photo_thumbnailUrl;
Photo_list({this.Photo_albumId, this.Photo_id, this.Photo_title, this.Photo_url, this.Photo_thumbnailUrl});
factory Photo_list.fromJson(Map json) {
return Photo_list(
Photo_albumId: json['albumId'] as int,
Photo_id: json['id'] as int,
Photo_title: json['title'] as String,
Photo_url: json['url'] as String,
Photo_thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final appTitle = 'Isolate Demo';
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class HomePage extends StatelessWidget {
final String title;
HomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? PhotosList(photos: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
);
}
}
class PhotosList extends StatelessWidget {
final List photos;
PhotosList({Key key, this.photos}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: photos.length,
itemBuilder: (context, index) {
return Image.network(photos[index].Photo_thumbnailUrl);
},
);
}
}
输出:
https://media.geeksforgeeks.org/wp-content/uploads/20200907174015/Record_2020-08-31-12-16-33_829c59ad18b7b7e1c4bdb99815829a48.mp4
想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处 前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!