🚅

【Flutter】Isolateの基礎知識

2021/01/03に公開

【Flutter】Isolate

はじめに

事前知識

  • Dartはシングルスレッド(メモリの競合は起こらない仕組み)

  • 並行処理を実施する場合に、アイソレート(Isolate)という仕組みを利用

    • 各Isolateでメモリは共有しない
    • 各Isolateでデータのやりとりはメッセージを利用
  • 作成方法

    • Isolate.spawn関数('dart:isolate'利用)
    • compute 関数('package:flutter/foundation.dart';利用)
      • Isolate をラップした compute 関数の方がシンプル
  • その他基本知識、知りたいことはFlutterでIsolateを用いた並列処理をするべきシーンとそのやり方 | by mono  | Flutter 🇯🇵 | Mediumに丁寧な記載があった

    • 簡単な確認のみ以下実施

compute 関数の確認

  • compute関数を利用しないで、時間が掛かる処理を実施する場合
    • 画面がカクつく
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          CircularProgressIndicator(),
          RaisedButton(
            child: Text('HeavyTask Start'),
            onPressed: () async {
              final result = heavyTask(1000000000); // 画面がカクつく
              // final result = await compute(heavyTask, 1000000000); // 画面がカクつかない
              print(result);
            },
          )
        ],
      ),
    );
  }
}

String heavyTask(int value) {
  String res;
  // 時間が掛かる処理と仮定
  for (int i = 0; i < value; ++i) {
    if (i == value - 1) res = 'Finish heavyTask!';
  }
  return res;
}

実行結果

  • compute関数を利用しないで、時間が掛かる処理を実施する場合
    • 画面がカクつかない
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          CircularProgressIndicator(),
          RaisedButton(
            child: Text('HeavyTask Start'),
            onPressed: () async {
              // final result = heavyTask(1000000000); // 画面がカクつく
              final result = await compute(heavyTask, 1000000000); // 画面がカクつかない
              print(result);
            },
          )
        ],
      ),
    );
  }
}

String heavyTask(int value) {
  String res;
  // 時間が掛かる処理と仮定
  for (int i = 0; i < value; ++i) {
    if (i == value - 1) res = 'Finish heavyTask!';
  }
  return res;
}

実行結果

Discussion