Flutter
Isolate 사용방법
flutter 개발하자
2021. 5. 31. 09:29
Isolate 사용 방법
compute의 경우 다른 예제 글들이 많으니 넘어가고, spawn의 방법에대해 알아보자.
isolate간의 통신을 위한 방법은 RecievePort를 통해 하는 것인데,
RecievePort
- isolata간에 메세지를 주고 받을 수 있는 포트
- RecievePort는 sendPort를 반환하는 SendPort getter를 갖고 있음
SendPort
- 지정된 RecievePort에 메세지를 보냄.
- SendPort를 통해 전송된 메세지는 지정된 RecievePort에 전송되고, RecievePort는 해당 메세지를 RecievePort의 listener를 통해 받을 수 있다.
Isolate.spawn
Isolate.spawn(함수, recievePort.sendPort)
- isolate를 생성하고, spawn의 첫 번째 인자로 들어온 함수를 실행시킴.
(이때의 함수는 static이거나 top-level function이여야 한다.)
(top-level function은 클래스나 main함수 외에 선언된 함수를 의미함,)
ex)
void foo() {} // A top-level function
class A {
static void bar() {} // A static method
void baz() {} // An instance method
}
void main() {
Function x;
// Comparing top-level functions.
x = foo;
assert(foo == x);
// Comparing static methods.
x = A.bar;
assert(A.bar == x);
// Comparing instance methods.
var v = A(); // Instance #1 of A
var w = A(); // Instance #2 of A
var y = w;
x = w.baz;
// These closures refer to the same instance (#2),
// so they're equal.
assert(y.baz == x);
// These closures refer to different instances,
// so they're unequal.
assert(v.baz != w.baz);
}
late Isolate isolate;
RecievePort recievePort = RecievePort();
isolate = Isolate.spawn(함수, receivePort.sendPort);
reciecePort.listen(들어온 데이터 처리 함수, onDone:(){});
static 함수(){
sendPort(데이터)
}
예제
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:isolate';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Isolate Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(key: null,title: 'Flutter Isolates'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({required Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late Isolate? _isolate;
bool _running = false;
static int _counter = 0;
String notification = "";
late ReceivePort _receivePort;
void _start() async {
_running = true;
_receivePort = ReceivePort();
_isolate = await Isolate.spawn(_checkTimer, _receivePort.sendPort);
_receivePort.listen(_handleMessage, onDone:() {
print("done!");
});
}
void _checkTimer(SendPort sendPort) async {
Timer.periodic(new Duration(seconds: 1), (Timer t) {
_counter++;
String msg = 'notification ' + _counter.toString();
print('SEND: ' + msg);
sendPort.send(msg);
});
}
void _handleMessage(dynamic data) {
print('RECEIVED: ' + data);
setState(() {
notification = data;
});
}
void _stop() {
if (_isolate != null) {
setState(() {
_running = false;
notification = '';
});
_receivePort.close();
_isolate!.kill(priority: Isolate.immediate);
_isolate = null;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
notification,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _running ? _stop : _start,
tooltip: _running ? 'Timer stop' : 'Timer start',
child: _running ? new Icon(Icons.stop) : new Icon(Icons.play_arrow),
),
);
}
}