Flutter后台任务管理插件easy_worker的使用

Flutter后台任务管理插件easy_worker的使用

使用Dart Isolate进行后台任务管理对于初学者来说可能不太容易,并且即使是经验丰富的开发者也需要编写大量的样板代码。尽管有许多包可以解决这个问题,但很少有包像easy_worker那样简单易用。

Easy Worker

EasyWorker可能是迄今为止最简单的处理Dart Isolate的方法。

特性

  1. 简单易学易用。
  2. 可以轻松启动长时间运行的任务或短期计算。
  3. 最简单的双向通信方式。

入门

添加easy_workerpubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  easy_worker:

使用方法

长时间运行的任务和主隔离区与工作隔离区之间的双向通信

你需要两样东西:

  1. 静态或顶层函数,例如这个阶乘计算器:
/// 这个函数接收一个数字(消息/负载等),并发送结果给父进程
void calculateFactorial(int number, Sender send) {
  int temp = number;
  number--;
  while (number > 0) {
    temp *= number;
    number--;
    // 模拟长时间运行的任务,阻塞操作
    sleep(const Duration(milliseconds: 100));
  }

  /// 完成后将计算结果发送回父进程
  send(temp);
}
  1. EasyWorker 或 EasyCompute 实例

A. 使用 EasyWorker

  1. 创建 EasyWorker 实例
// EasyWorker<Result Type, Input Type>
final worker = EasyWorker<int, int>(
  Entrypoint(calculateFactorial),
  workerName: "Factorial Calculator",
  initialMessage: 0, // 可选:此工作者的初始负载为0
);

await worker.waitUntilReady();
  1. 如何发送和接收数据
  • 获取第一个结果
final result = await worker.stream.first;
  • 监听从隔离区传来的所有结果
worker.onMessage((message) {
  print("Message From Worker: $message");
});
  • 向工作者发送消息
/// 发送6作为负载,以获取6的阶乘
worker.send(6);

B. 使用 EasyCompute:可重用的隔离区,适用于高性能应用

  1. 创建 EasyCompute 实例
// EasyCompute<Result Type, Input Type>
final worker = EasyCompute<int, int>(
  ComputeEntrypoint(calculateFactorial),
  workerName: "Factorial Calculator",
);

await worker.waitUntilReady();
  1. 获取结果
final result = await worker.compute(6);

print(result); // 输出结果

在不再需要时释放资源

worker.dispose();

常见问题

简单的一次性任务怎么办?

/// 直接调用compute并传递入口点和负载
final result = await EasyWorker.compute<int, int>(calculateFactorial, 5);

print(result); // 输出 120

额外信息

FAQ

  1. 既然已经有其他类似的包,为什么还需要这个包?

    • 大多数包都有一定的学习曲线和技术复杂性,而这个包则尽量简化了这些复杂性。
  2. 我想实现某个功能,应该怎么做?

    • 你可以在GitHub上创建一个功能请求。

许可证

  • MIT

完整示例代码

import 'dart:io';

import 'package:easy_worker/easy_worker.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Calculate Factorial'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  /// 声明工作者
  late final EasyWorker<int, int> worker;

  [@override](/user/override)
  void initState() {
    super.initState();

    /// 初始化工作者,带第一个负载
    worker = EasyWorker(
      Entrypoint(calculateFactorial),
      workerName: "Factorial Calculator",
      initialMessage: _counter,
    );
  }

  static void calculateFactorial(int number, Sender send) {
    /// 让StreamBuilder知道处理已经开始
    send('loading');

    int temp = number;
    number--;
    while (number > 0) {
      temp *= number;
      number--;
      // 模拟长时间运行的任务,阻塞操作
      sleep(const Duration(milliseconds: 100));
    }

    /// 完成后发送计算结果
    send(temp);
  }

  [@override](/user/override)
  void dispose() {
    /// 释放工作者进程
    worker.dispose();
    super.dispose();
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
      worker.send(_counter);
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Factorial of $_counter is',
              style: Theme.of(context).textTheme.displayMedium,
            ),

            /// 显示从工作者接收到的消息/结果
            StreamBuilder(
              stream: worker.stream,
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (snapshot.data == 'loading') {
                  return const Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Center(
                      child: CircularProgressIndicator(),
                    ),
                  );
                }

                return Text(
                  snapshot.data.toString(),
                  style: Theme.of(context).textTheme.displayLarge,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment and Calculate Factorial',
        child: const Icon(Icons.add),
      ),
    );
  }
}

更多关于Flutter后台任务管理插件easy_worker的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter后台任务管理插件easy_worker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用easy_worker插件来管理后台任务的示例代码。easy_worker是一个Flutter插件,用于在后台执行长时间运行的任务,而不会阻塞UI线程。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加easy_worker依赖:

dependencies:
  flutter:
    sdk: flutter
  easy_worker: ^x.y.z  # 请替换为最新版本号

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

2. 创建后台任务类

接下来,你需要创建一个实现Worker接口的类,这个类将包含你想要在后台执行的任务逻辑。

import 'package:easy_worker/easy_worker.dart';

class MyBackgroundTask extends Worker {
  @override
  Future<void> executeTask() async {
    // 在这里编写你的后台任务逻辑
    print("后台任务开始");
    await Future.delayed(Duration(seconds: 5)); // 模拟长时间运行的任务
    print("后台任务完成");
  }
}

3. 注册并启动后台任务

在你的主应用代码中,你需要注册并启动这个后台任务。

import 'package:flutter/material.dart';
import 'package:easy_worker/easy_worker.dart';
import 'my_background_task.dart'; // 导入你创建的后台任务类

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

  // 注册并启动后台任务
  EasyWorker.register<MyBackgroundTask>(
    'my_background_task_id', // 任务的唯一标识符
    params: {'key': 'value'}, // 可选的参数,传递给后台任务的参数
  ).then((worker) {
    worker.start().then((result) {
      print("后台任务启动成功: $result");
    }).catchError((error) {
      print("启动后台任务失败: $error");
    });
  }).catchError((error) {
    print("注册后台任务失败: $error");
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter 后台任务管理'),
        ),
        body: Center(
          child: Text('后台任务已启动,请查看控制台输出。'),
        ),
      ),
    );
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用。在控制台中,你应该能够看到后台任务开始和完成的打印信息。

注意事项

  • 确保你的应用有适当的权限来执行后台任务,特别是在Android和iOS平台上。
  • easy_worker插件在后台执行任务时可能会受到操作系统策略的限制,特别是在iOS上。因此,测试你的应用在真实设备上的行为是很重要的。
  • 如果你的后台任务需要定期执行,你可能需要结合其他插件或系统服务(如Android的WorkManager或iOS的Background Tasks)来实现。

这个示例代码展示了如何使用easy_worker插件在Flutter应用中管理后台任务。根据你的具体需求,你可能需要进一步定制和扩展这个示例。

回到顶部