[Dart] Dart에서 Isolates(아이솔레이트) 사용하기
1️⃣ 개요
현재 진행하고 있는 프로젝트에서 1. 위치 정보를 가져옴 2. 가져온 위치정보를 Request로 API를 호출한 뒤 특정 화면에 진입하는 로직이 있음
그런데 이 위치 정보를 가져오는 과정이 오래 걸려서 (사실 난 잘 모르겠지만 어쨌든) 이 작업을 메인 UI 스레드가 아닌 백그라운드 스레드로 동작시키라는 업무를 지시 받음
결론은 성능에 큰 차이는 없었고 (내가 보기엔 너무 작은 태스크라서 그런 것 같다) 체감상 더 느려진 것 같은 기분이었는데, 아직도 이 부분을 더 좋은 코드로 빠르게 동작시키려면 어떻게 해야하는 지 고민이 필요함…
참고로 Dart에서 비동기 프로그래밍에 관한 포스팅은 여기를 클릭하시면 확인할 수 있음!
2️⃣ pubspec.yaml 세팅
위치 정보를 가져오기 위해 geolocator 라이브러리를 사용 Flutter geolocator
1
2
dependencies:
geolocator: ^12.0.0
3️⃣ 아이솔레이트 클래스 생성
백그라운드 스레드 작업을 수행해야하는 화면에서 private으로 아이솔레이트 클래스를 생성
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
class _IsolateData {
final RootIsolateToken token;
final Function fuction;
final SendPort answerPort;
_IsolateData({
required this.token,
required this.function,
required this.answerPort,
})
}
Future<dynamic> computeIsolate(Future Function() function) async {
final receivePort = ReceivePort();
var rootToken = RootIsolateToken.instance!;
await Isolate.spawn<_IsolateData>(
_isolateEntry,
_IsolateData(
token: rootToken,
function: function,
answerPort: receivePort.sendPort,
),
);
return await receivePort.first;
}
void _isolateEntry(_IsolateData isolateData) async {
BackgroundIsolateBinaryMessenger.ensureInitialized(isolateData.token);
final answer = await isolateData.function();
isolateData.answerPort.send(answer);
}
4️⃣ 아이솔레이트 작업 수행
1
2
3
4
5
6
Position position = await computeIsolate(_getCurrentPosition);
static Future<Position> _getCurrentPosition() async {
final position = await LocationManager.instance.getCurrentPosition();
return position;
}
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
class LocationManager {
LocationManager._();
static final LocationManager _instance = LocationManager._();
static LocationManager get instance => _instance;
Future<bool> checkLocationPermission() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
return false;
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.always ||
permission == LocationPermission.whileInUse) {
return true;
} else {
return false;
}
}
Future<Position> getCurrentPosition() async {
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
}
}
Leave a comment