Flutter应用关闭(终止)时如何实现每分钟定时执行代码
应用关闭状态下定时发起网络请求的实现方案
提前说明:移动端系统对后台进程、定时任务有严格的省电策略限制,普通第三方应用无法做到应用关闭后严格每分钟执行一次代码,下面是可落地的实现方式和限制说明
现有代码适配
你已经写好的MultipartRequest请求逻辑不需要修改,只需要把它放到后台任务的执行回调里即可。
具体实现步骤
跨平台Flutter场景下直接用workmanager做后台任务调度即可,它封装了Android系统原生WorkManager、iOS原生BGTaskScheduler能力,不需要自己写双端原生代码。
- 添加依赖到项目
pubspec.yaml文件:
dependencies: workmanager: ^0.5.2 # 你项目中已引入http库的话不需要重复添加 http: ^1.1.0
- 注册后台任务回调,注册周期调度任务:
import 'package:flutter/material.dart'; import 'package:workmanager/workmanager.dart'; import 'package:http/http.dart' as http; // 注意:这个回调必须是顶级函数或者类静态方法,要加vm:entry-point注解保证AOT编译后不被混淆 @pragma('vm:entry-point') void backgroundTaskDispatcher() { Workmanager().executeTask((taskId, inputParams) async { // 直接把你现有的请求逻辑复制到这里 const kTimeOutDuration = Duration(seconds: 10); // 以下参数替换成你项目实际的请求配置 const requestMethod = "POST"; const requestUrl = "你的业务接口地址"; final requestHeaders = <String, String>{}; final requestFields = <String, String>{}; try { final request = http.MultipartRequest(requestMethod, Uri.parse(requestUrl)) ..headers.addAll(requestHeaders) ..fields.addAll(requestFields); final response = await request.send().timeout(kTimeOutDuration); // 这里写拿到响应后的处理逻辑,比如检测到新内容就弹出本地通知提醒用户 debugPrint("后台请求执行完成,状态码:${response.statusCode}"); // 返回true标记任务执行成功 return true; } catch (err) { debugPrint("后台请求执行失败:$err"); // 返回false系统会按照默认策略安排重试 return false; } }); } void main() { WidgetsFlutterBinding.ensureInitialized(); // 初始化后台任务调度器 Workmanager().initialize( backgroundTaskDispatcher, isInDebugMode: false, ); // 注册周期执行任务 Workmanager().registerPeriodicTask( "new_content_check_task", "checkNewContent", // Android系统强制周期任务最小间隔为15分钟,设置小于该值会被系统自动调整为15分钟 frequency: const Duration(minutes: 15), existingWorkPolicy: ExistingWorkPolicy.replace, constraints: Constraints( networkType: NetworkType.connected, // 仅在设备联网时执行任务 ), ); runApp(const MyApp()); }
平台限制说明
- Android端:系统为了控制功耗,普通应用的周期后台任务最小间隔为15分钟,无法做到每分钟执行;如果用户手动划掉应用、开启省电模式、或者在国产定制ROM上没有给应用开放自启动、后台运行、关闭电池优化权限,任务会出现延迟、不执行的情况。
- iOS端:系统对后台任务管控更严格,周期任务的执行时机完全由系统根据用户使用习惯、设备电量、网络状态动态决定,执行间隔通常在数小时级别,不可能支持分钟级轮询;如果应用尝试在后台长时间保活跑轮询,提交App Store审核会被直接拒绝。
如果你需要做到新内容及时触达用户,不要走客户端轮询的方案,最优解是接入服务端推送通道(安卓用各厂商推送、FCM,iOS用APNs),服务端检测到新内容时主动推送给客户端,客户端收到推送后再拉取对应内容,这是唯一稳定、合规、低功耗的实现方式。
内容的提问来源于stack exchange,提问作者Hadi HG
相关产品推荐
相关产品推荐

