Want to parse JSON in the background in Flutter? By default, Dart apps do all of their work on a single thread. In many cases, this model simplifies coding and is fast enough that it does not result in poor app performance or stuttering animations, often called “jank.”
This example uses the following steps:
1. Add the http package.
2. Make a network request using the http package.
3. Convert the response into a list of photos.
4. Move this work to a separate isolate.
Here is the complete example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | import 'dart:async'; import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; Future<List<Photo>> fetchPhotos(http.Client client) async { final response = await client.get('https://jsonplaceholder.typicode.com/photos'); // Use the compute function to run parsePhotos in a separate isolate. return compute(parsePhotos, response.body); } // A function that converts a response body into a List<Photo>. List<Photo> parsePhotos(String responseBody) { final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>(); return parsed.map<Photo>((json) => Photo.fromJson(json)).toList(); } class Photo { final int albumId; final int id; final String title; final String url; final String thumbnailUrl; Photo({this.albumId, this.id, this.title, this.url, this.thumbnailUrl}); factory Photo.fromJson(Map<String, dynamic> json) { return Photo( albumId: json['albumId'] as int, id: json['id'] as int, title: json['title'] as String, url: json['url'] as String, 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 MyHomePage extends StatelessWidget { final String title; MyHomePage({Key key, this.title}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: FutureBuilder<List<Photo>>( 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<Photo> 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].thumbnailUrl); }, ); } } |
If you like this question & answer and want to contribute, then write your question & answer and email to freewebmentor[@]gmail.com. Your question and answer will appear on FreeWebMentor.com and help other developers.