Flutter后台任务管理插件work的使用
Flutter后台任务管理插件work的使用
work
是一个用于简化 HTTP 请求的 Flutter 插件,基于 dio
实现。它封装了 HTTP 业务接口协议,并提供了一套标准且一致的接口编写与执行流程。
安装
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
work: ^7.0.0
简单的 GET 请求实现
class GetWork extends Work<String> {
const GetWork(this.name, this.age);
final String name;
final int age;
[@override](/user/override)
FutureOr<dynamic> onFillParams(WorkData<String> data) => {
'name': name,
'age': age,
};
[@override](/user/override)
String? onRequestSuccessful(WorkData<String> data) =>
data.response!.data['args'].toString();
[@override](/user/override)
String onUrl(WorkData<String> data) => '/get';
}
简单的 POST 请求
class PostJsonWork extends Work<String> {
const PostJsonWork(this.name, this.age);
final String name;
final int age;
[@override](/user/override)
HttpMethod onHttpMethod(WorkData<String> data) => HttpMethod.post;
[@override](/user/override)
String? onContentType(WorkData<String> data) => 'application/json';
[@override](/user/override)
FutureOr<dynamic> onFillParams(WorkData<String> data) => {
'name': name,
'age': age,
};
[@override](/user/override)
String? onRequestSuccessful(WorkData<String> data) =>
data.response!.data['json'].toString();
[@override](/user/override)
String onUrl(WorkData<String> data) => '/post';
}
调用接口
final work = await const GetWork('超悟空', 32).start();
print('work result ${work.result} message ${work.message}');
全局设置和通用处理逻辑实现
workConfig
是默认的全局配置,可以在此处设置全局的 dio
配置,也可以在此处设置全局的请求处理逻辑 WorkDelegate
。
void main() {
workConfig = WorkConfig(
dio: Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 30),
sendTimeout: const Duration(seconds: 30),
contentType: 'application/x-www-form-urlencoded',
baseUrl: 'http://httpbin.org/',
),
),
delegate: WorkDelegateImp(),
);
}
处理公司专用响应协议
所有请求和响应数据都在 WorkData
中,可以扩展 WorkData
以添加自定义只读属性方便使用。也可以利用 WorkData.extra
实现写属性扩展。
extension WorkDataExtension<T> on WorkData<T> {
/// 协议错误码
int get errorCode => response?.data['errorCode'] ?? 0;
/// 原始响应结果数据
dynamic get resultData => response?.data['result'];
}
class WorkDelegateImp extends WorkDelegate {
[@override](/user/override)
bool onRequestResult(WorkData data) => data.errorCode == 0;
[@override](/user/override)
String? onParamsError(WorkData data) => '参数不合法';
[@override](/user/override)
String onNetworkError(data) => '网络连接失败,当前网络不可用';
[@override](/user/override)
String onNetworkRequestFailed(data) => '请求失败,服务器异常';
[@override](/user/override)
String onParseFailed(data) => '请求失败,服务器异常';
[@override](/user/override)
String onRequestFailedMessage(data) =>
data.response!.data['message'] ?? '操作失败';
[@override](/user/override)
String onRequestSuccessfulMessage(data) =>
data.response!.data['message'] ?? '操作成功';
}
支持请求类型
HttpMethod
中的类型:get
、post
、put
、delete
、head
、patch
。- 上传文件时请实现
Work.onContentType
并设置为multipart/form-data
,参数中的文件需要用File
或UploadFileInfo
类型包装,支持文件列表。 - 下载文件时可以自己处理字节流,需要实现
Work.onResponseType
并指定自己需要的响应格式,也可以参考DownloadWork
实现一个快捷下载类,此方式使用dio.download
下载。
其他
Work
中还有很多生命周期方法,用于做有限的接口扩展和定制。- 原则是接口数据处理由接口自己(即
Work
)处理。 - 更多具体用法如上传下载等可以参考 测试用例。
示例代码
import 'dart:io';
import 'package:json_annotation/json_annotation.dart';
import 'package:work/work.dart';
part 'main.g.dart';
void main() async {
workConfig = WorkConfig(
dio: Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 30),
sendTimeout: const Duration(seconds: 30),
contentType: 'application/x-www-form-urlencoded',
),
),
delegate: WorkDelegateImp(),
);
final data = await TestWork('xxx').start();
if (data.success) {
print(data.result);
} else {
print(data.message);
print(data.errorCode);
}
final download = await DownloadWork(
path: 'file:/xxx/test.jpg',
key: 'key',
resNo: 123,
).start();
if (download.success) {
// show('file:/xxx/test.jpg')
}
final upload = await UploadWork(File('test.jpg')).start();
if (upload.success) {
print(upload.result);
}
}
/// 简化的[WorkData]类实现
///
/// 使用特定的公司接口协议描述。
///
/// ``` http协议
/// 所有接口响应数据格式
///
/// json结构
///
/// {
/// "errorCode":0, // 错误码,成功时返回0
/// "message":null, // 业务消息字符串,可以是成功时用于显示的信息,也可以是失败时的提示信息
/// "result": {} // 真正响应的有效业务数据,任意类型
/// }
///
/// ```
extension WorkDataExtension<T> on WorkData<T> {
/// 协议错误码
int get errorCode => response?.data['errorCode'] ?? 0;
/// 原始响应结果数据
dynamic get resultData => response?.data['result'];
}
/// 实现通用处理
///
/// ``` http协议
/// 所有接口响应数据格式
///
/// json结构
///
/// {
/// "errorCode":0, // 错误码
/// "message":null, // 业务消息字符串,可以是成功时用于显示的信息,也可以是失败时的提示信息
/// "result": {} // 真正响应的有效业务数据,任意类型
/// }
///
/// ```
class WorkDelegateImp extends WorkDelegate {
[@override](/user/override)
bool onRequestResult(WorkData data) => data.errorCode == 0;
[@override](/user/override)
String? onParamsError(WorkData data) => '参数不合法';
[@override](/user/override)
String onNetworkError(data) => '网络连接失败,当前网络不可用';
[@override](/user/override)
String onNetworkRequestFailed(data) => '请求失败,服务器异常';
[@override](/user/override)
String onParseFailed(data) => '请求失败,服务器异常';
[@override](/user/override)
String onRequestFailedMessage(data) =>
data.response!.data['message'] ?? '操作失败';
[@override](/user/override)
String onRequestSuccessfulMessage(data) =>
data.response!.data['message'] ?? '操作成功';
}
class TestWork extends Work<String> {
const TestWork(this.param1);
/// 请求参数1
final String param1;
[@override](/user/override)
FutureOr<dynamic> onFillParams(WorkData<String> data) => {
'param1': param1,
};
[@override](/user/override)
FutureOr<String?> onRequestSuccessful(WorkData<String> data) {
return data.resultData['account'];
}
[@override](/user/override)
String onUrl(WorkData<String> data) => 'https://api.example.com/test';
}
[@JsonSerializable](/user/JsonSerializable)()
class DownloadWork extends Work<void> {
const DownloadWork({
required this.path,
required this.key,
required this.resNo,
});
/// 存放路径
[@JsonKey](/user/JsonKey)(includeToJson: false)
final String path;
/// 请求参数key
final String key;
/// 请求参数resNo
final int resNo;
[@override](/user/override)
FutureOr<dynamic> onFillParams(WorkData<void> data) =>
_$DownloadWorkToJson(this);
[@override](/user/override)
FutureOr<void> onRequestSuccessful(WorkData<void> data) {}
[@override](/user/override)
FutureOr<void> onPostOptions(WorkData<void> data) {
data.options!.downloadPath = path;
}
[@override](/user/override)
String onRequestFailedMessage(data) => '下载失败';
[@override](/user/override)
String onRequestSuccessfulMessage(data) => '下载成功';
[@override](/user/override)
String onUrl(WorkData<void> data) => 'https://api.example.com/test.jpg';
}
[@JsonSerializable](/user/JsonSerializable)()
class UploadWork extends Work<String> {
const UploadWork(this.file);
/// 需要上传的文件
[@JsonKey](/user/JsonKey)(toJson: workFileToJsonConvert)
final File file;
[@override](/user/override)
FutureOr<dynamic> onFillParams(WorkData<String> data) =>
_$UploadWorkToJson(this);
[@override](/user/override)
FutureOr<String?> onRequestSuccessful(WorkData<String> data) {
return data.resultData; // 假设返回的是文件url
}
[@override](/user/override)
String onUrl(WorkData<String> data) => 'https://api.example.com/upload';
}
更多关于Flutter后台任务管理插件work的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter后台任务管理插件work的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,workmanager
是一个流行的插件,用于在后台执行任务。这个插件允许你安排定期或一次性任务,即使应用程序处于关闭状态也能运行。下面是一个使用 workmanager
插件的示例代码,展示如何设置和使用后台任务。
步骤 1: 添加依赖
首先,在你的 pubspec.yaml
文件中添加 workmanager
依赖:
dependencies:
flutter:
sdk: flutter
workmanager: ^0.7.4 # 请检查最新版本
然后运行 flutter pub get
来获取依赖。
步骤 2: 配置 Android 和 iOS
Android 配置
在 android/app/src/main/AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
在 android/app/src/main/kotlin/[your_package_name]/Application.kt
(或 MainActivity.kt
,取决于你的项目结构)中初始化 Workmanager
:
package com.example.yourapp
import android.app.Application
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.workmanager.WorkmanagerPlugin
class Application : Application() {
override fun onCreate() {
super.onCreate()
WorkmanagerPlugin.initialize(
this, // your application context
WorkmanagerPlugin.CallbackDispatcher(this) // Dispatcher to handle background callbacks
)
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// Keep this line to initialize the Workmanager plugin.
WorkmanagerPlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger)
}
}
别忘了在 android/app/src/main/AndroidManifest.xml
中指定你的 Application 类:
<application
android:name=".Application"
... >
...
</application>
iOS 配置
在 ios/Runner/Info.plist
中添加以下权限(如果需要):
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
<string>remote-notification</string>
</array>
在 ios/Runner/AppDelegate.swift
中初始化 Workmanager
(如果你使用的是 Swift):
import UIKit
import Flutter
import workmanager
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
WorkmanagerPlugin.setPluginRegistrantCallback { registry in
GeneratedPluginRegistrant.register(with: registry)
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
步骤 3: Flutter 代码实现
在你的 Flutter 项目中,使用以下代码来注册和调度后台任务:
import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
// 在这里执行你的后台任务
print("Background task running: $task");
print("Input data: $inputData");
return Future.value(true);
});
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Workmanager().initialize(
callbackDispatcher,
isInDebugMode: true, // 仅在开发模式下设置为 true
);
// 注册一个定期任务
Workmanager().registerOneOffTask(
"uniqueTaskName",
"simpleTask", // 这是你在 native 代码中定义的回调任务的名称
inputData: {'someKey': 'someValue'},
initialDelay: const Duration(seconds: 10), // 延迟 10 秒后开始任务
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Workmanager Demo'),
),
body: Center(
child: Text('Check the console for background task logs'),
),
),
);
}
}
注意
- 权限:确保在运行时请求必要的权限,尤其是在 Android 上。
- 电池优化:某些设备可能会因为电池优化而限制后台任务的执行。
- 测试:在真机上进行测试,因为模拟器可能不会触发所有后台任务。
这段代码展示了如何使用 workmanager
插件在 Flutter 应用中注册和执行后台任务。根据你的具体需求,你可以调整任务的调度逻辑和任务执行的代码。