일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Houdini
- vim
- Algorithm
- c# 윈폼
- 도커
- dart 언어
- docker
- jupyter lab
- C언어 포인터
- Data Structure
- github
- 깃
- c# 추상 클래스
- Python
- 유니티
- 구조체
- HTML
- gitlab
- 플러터
- c#
- git
- 포인터
- c# winform
- c언어
- C++
- C# delegate
- 다트 언어
- jupyter
- Unity
- Flutter
Archives
- Today
- Total
nomad-programmer
[Programming/Flutter] isolate : 백그라운드에서의 JSON 파싱 본문
isolate는 다른 언어에서의 thread 개념이라도 생각면된다. Flutter는 main isolate에서 앱이 실행된다. 그런데 비싼 비용의 데이터를 불러올때면 툭툭 끊기는 애니메이션을 야기할 수 있다. 이렇게 툭툭 끊기는 애니메이션을 "jank"라고 부른다.
허나 isolate를 사용하면 jank가 없는 애니메이션을 볼 수 있을뿐더러 성능도 올라간다.
flutter-ko.dev/docs/cookbook/networking/background-parsing
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('isolate 예제'),
),
body: FutureBuilder<List<Photo>>(
future: fetchPhotos(http.Client()),
builder: (BuildContext context, AsyncSnapshot<List<Photo>> snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
}
return snapshot.hasData
? PhotoList(photos: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
);
}
}
class PhotoList extends StatelessWidget {
final List<Photo> photos;
const PhotoList({Key key, this.photos}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: photos.length,
itemBuilder: (BuildContext context, int index) {
return Image.network(photos[index].thumbnailUrl);
},
);
}
}
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,
);
}
}
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
// compute 함수를 사용하여 parsePhotos를 별도 isolate에서 수행한다.
return compute(parsePhotos, response.body);
}
// 응답 결과를 List<Photo>로 변환하는 함수
List<Photo> parsePhotos(String reponseBody) {
final List<Map<String, dynamic>> parsed =
json.decode(reponseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
compute 함수를 사용하여 파싱하고 변환하는 작업을 백그라운드 isolate으로 옮긴다.
compute() 함수는 오래 걸리는 함수를 백그라운드 isolate에서 돌리고 그 결과를 반환한다.
위의 예제에서는 parsePhotos() 함수를 백그라운드에서 수행한다.
FutureBuilder
Flutter의 경우 비동기 통신을 사용한다. 이것은 동기식 통신과 다르게 서버에서 데이터를 모두 받아오기전, 화면을 그려줄 수 있는 되는 장점이 있다.
위의 예제에서 FutureBuilder를 사용했다. FutureBuilder를 사용한 이유는 Future를 사용하는 이유처럼 데이터를 모두 다 받기전에 먼저 받은 데이터를 UI에 그리기위해서이다.
만약 FutureBuilder가 없다면 데이터가 모두 다 받아지기를 기다린 후, 데이터를 UI에 그릴것이다.
'Programming > Flutter' 카테고리의 다른 글
[Programming/Flutter] Provider 메소드 확장 (select, read, watch) (0) | 2020.10.28 |
---|---|
[Programming/Flutter] SQLite를 이용한 데이터 처리 (0) | 2020.10.24 |
[Programming/Flutter] CustomPainter를 이용한 차트(그래프) (0) | 2020.10.22 |
[Dart] Unit Test (유닛 테스트) (0) | 2020.10.22 |
[Flutter] StatefulWidget 클래스 사용 시점 (0) | 2020.10.18 |
Comments