Flutter隔离执行环境插件isolate_classy的使用

Flutter隔离执行环境插件isolate_classy的使用

通过使用isolate_classy插件,您可以轻松地将异步函数放在隔离环境中运行。只需在函数名称后添加.isolate.isolateX(其中X是数字[0-6]),即可实现这一功能。

特性

只需调用.isolate.isolateX,就可以使您的异步函数在隔离环境中运行。

开始使用

首先,在项目中导入isolate_classy包:

import 'package:isolate_classy/isolate_classy.dart';

使用方法

1. 无命名参数的异步函数在隔离中运行

只需在函数名后添加.isolate,即可使其在隔离环境中运行。

Future<int> func(int a1, int a2, int a3) async {
  // 函数实现
}

// 在主线程中运行
await func(1, 2, 3);

// 在新的隔离中运行
await func.isolate(1, 2, 3);
2. 带命名参数的异步函数在隔离中运行

如果函数有命名参数,则在调用时也应使用命名参数。此外,如果您希望指定返回值类型,可以在调用时进行指定。

Future<int> func({double width, double height, Color? color}) async {
  // 函数实现
}

Future<int> func6(int a1, int a2, int a3, int a4, int a5, int a6, {double width, double height, Color? color}) async {
  // 函数实现
}

// 调用时没有位置参数
await func.isolate({#width: 100, #height: 200, #color: Colors.blue});

// 调用时有一个位置参数
await func1.isolate1(1, {#width: 100, #height: 200, #color: Colors.blue});

// 调用时有六个位置参数
await func1.isolate6(1, 2, 3, 4, 5, 6, {#width: 100, #height: 200, #color: Colors.blue});

额外信息

这篇文章解释了该插件背后的工作原理。

如果一个带有命名参数的异步函数使用返回值,您需要指定返回值类型。

int ret = await func.isolate({#width: 100, #height: 200, #color: Colors.blue});
// 或者
ret = await func.isolate<int>({#width: 100, #height: 200, #color: Colors.blue});

完整示例代码

import 'dart:developer';
import 'dart:isolate';
import 'dart:math';
import 'package:isolate_classy/isolate_classy.dart';

Future<void> main() async {
  //
  // 只有带位置参数的函数(最多6个)
  // 只需在函数名后添加 `.isolate` 即可使其在隔离中运行
  var result = await positionArgument0.isolate();
  print('positionArgument0 返回 $result');
  result = await positionArgument1.isolate(1);
  print('positionArgument1 返回 $result');
  result = await positionArgument2.isolate(1, 2);
  print('positionArgument2 返回 $result');
  result = await positionArgument3.isolate(1, 2, 3);
  print('positionArgument3 返回 $result');

  result = await positionArgument4.isolate(1, 2, 3, 4);
  print('positionArgument4 返回 $result');
  result = await positionArgument5.isolate(1, 2, 3, 4, 5);
  print('positionArgument5 返回 $result');
  result = await positionArgument6.isolate(1, 2, 3, 4, 5, 6);
  print('positionArgument6 返回 $result');

  //
  // 带命名参数的函数,在隔离中运行(位置参数最多6个)
  // 如果函数有1个位置参数则称为 `.isolate1`,2个位置参数则称为 `.isolate2`,直接调用 `.isolate`
  String value = await nameArgument0.isolate({#desc: "无位置参数的带命名参数的函数"});
  print('nameArgument0 返回 $value');
  value = await nameArgument1.isolate1(1, {#desc: "1个位置参数的带命名参数的函数"});
  print('nameArgument1 返回 $value');
  value = await nameArgument2.isolate2(1, 2, {#desc: "2个位置参数的带命名参数的函数"});
  print('nameArgument2 返回 $value');
  value = await nameArgument3.isolate3(1, 2, 3, {#desc: "3个位置参数的带命名参数的函数"});
  print('nameArgument3 返回 $value');

  value = await nameArgument4.isolate4(1, 2, 3, 4, {#desc: "4个位置参数的带命名参数的函数"});
  print('nameArgument4 返回 $value');
  value = await nameArgument5.isolate5(1, 2, 3, 4, 5, {#desc: "5个位置参数的带命名参数的函数"});
  print('nameArgument5 返回 $value');
  value = await nameArgument6.isolate6(1, 2, 3, 4, 5, 6, {#desc: "6个位置参数的带命名参数的函数"});
  print('nameArgument6 返回 $value');
}

Future<String> nameArgument0({required String desc, String? other}) async {
  print("nameArgument0:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:${Random().nextInt(1000000)}, other=$other");
}

Future<String> nameArgument1(int a1, {required String desc, String? other}) async {
  print("nameArgument1:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:$a1, other=$other");
}

Future<String> nameArgument2(int a1, int a2, {required String desc, String? other}) async {
  print("nameArgument2:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:${a1 + a2}, other=$other");
}

Future<String> nameArgument3(int a1, int a2, int a3, {required String desc, String? other}) async {
  print("nameArgument3:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:${a1 + a2 + a3}, other=$other");
}

Future<String> nameArgument4(int a1, int a2, int a3, int a4, {required String desc, String? other}) async {
  print("nameArgument4:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:${a1 + a2 + a3 + a4}, other=$other");
}

Future<String> nameArgument5(int a1, int a2, int a3, int a4, int a5, {required String desc, String? other}) async {
  print("nameArgument5:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:${a1 + a2 + a3 + a4 + a5}, other=$other");
}

Future<String> nameArgument6(int a1, int a2, int a3, int a4, int a5, int a6, {required String desc, String? other}) async {
  print("nameArgument6:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value("$desc:${a1 + a2 + a3 + a4 + a5 + a6}, other=$other");
}

Future<int> positionArgument0() async {
  print("positionArgument0:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(Random().nextInt(1000000));
}

Future<int> positionArgument1(int a1) async {
  print("positionArgument1:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(a1);
}

Future<int> positionArgument2(int a1, int a2) async {
  print("positionArgument2:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(a1 + a2);
}

Future<int> positionArgument3(int a1, int a2, int a3) async {
  print("positionArgument3:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(a1 + a2 + a3);
}

Future<int> positionArgument4(int a1, int a2, int a3, int a4) async {
  print("positionArgument4:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(a1 + a2 + a3 + a4);
}

Future<int> positionArgument5(int a1, int a2, int a3, int a4, int a5) async {
  print("positionArgument5:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(a1 + a2 + a3 + a4 + a5);
}

Future<int> positionArgument6(int a1, int a2, int a3, int a4, int a5, int a6) async {
  print("positionArgument6:${Service.getIsolateId(Isolate.current)}");
  await Future.delayed(const Duration(microseconds: 100));
  return Future.value(a1 + a2 + a3 + a4 + a5 + a6);
}

更多关于Flutter隔离执行环境插件isolate_classy的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter隔离执行环境插件isolate_classy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用isolate_classy插件来创建隔离执行环境的代码示例。isolate_classy是一个用于简化Dart isolate(隔离区)使用的Flutter插件。通过它,你可以在不阻塞UI线程的情况下执行耗时操作。

首先,确保你的pubspec.yaml文件中已经添加了isolate_classy依赖:

dependencies:
  flutter:
    sdk: flutter
  isolate_classy: ^最新版本号 # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,让我们编写一些代码来演示如何使用isolate_classy

示例代码

  1. 创建一个耗时操作

首先,我们定义一个耗时操作,比如计算一个大数的阶乘。

import 'package:isolate_classy/isolate_classy.dart';

class ComputeTask extends IsolateTask<int, int> {
  @override
  int compute(int input) {
    int result = 1;
    for (int i = 1; i <= input; i++) {
      result *= i;
    }
    return result;
  }
}
  1. 在Flutter应用中调用这个耗时操作

在你的Flutter应用中,你可以使用IsolateClassy来启动这个任务并在完成后获取结果。

import 'package:flutter/material.dart';
import 'package:isolate_classy/isolate_classy.dart';
import 'compute_task.dart'; // 假设你将上面的代码放在compute_task.dart文件中

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Isolate Classy Example'),
        ),
        body: Center(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _result = 'Calculating...';

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          _result,
          style: TextStyle(fontSize: 24),
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: _calculateFactorial,
          child: Text('Calculate Factorial of 20'),
        ),
      ],
    );
  }

  void _calculateFactorial() async {
    setState(() {
      _result = 'Calculating...';
    });

    final task = ComputeTask();
    final result = await IsolateClassy.execute(task, 20); // 20是要计算的阶乘数

    setState(() {
      _result = 'Factorial of 20 is $result';
    });
  }
}

在这个示例中,我们创建了一个ComputeTask类来执行阶乘计算,并在MyHomePage中通过IsolateClassy.execute方法来启动这个任务。当任务完成时,我们更新UI以显示结果。

注意事项

  • 确保你理解isolate的工作方式,特别是关于数据传递和同步的限制。在isolate之间传递数据需要通过消息传递机制,且传递的数据需要是可序列化的。
  • 在实际开发中,你可能需要处理更多的错误情况和边界条件,比如isolate执行失败或超时。

希望这个示例能帮助你理解如何在Flutter项目中使用isolate_classy来创建隔离执行环境。

回到顶部