如何在Flutter中注册网络连接事件监听器,实现联网自动同步离线数据
Flutter跨平台网络状态监听及离线数据自动上传实现方案
通用前置准备
- 先将所有离线操作产生的数据做本地持久化存储,推荐用
drift或者sqflite这类进程关闭后数据不会丢失的持久化库 - 提前封装好离线数据上传逻辑,确保任务触发时可以直接调用
实现思路
Flutter本身没有自带跨平台的系统级网络状态监听唤醒能力,需要借助双端原生系统的后台任务调度能力实现,不需要自己做轮询,完全由系统触发任务,资源消耗极低,应用被系统关闭也能正常执行。
双端适配方案(原生实现)
Android端
安卓系统可以通过WorkManager的约束触发机制实现,不需要手动注册广播:
- 首先在AndroidManifest.xml添加必要权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> - 构建带网络约束的一次性任务,交给系统调度:
val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build() val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>() .setConstraints(constraints) .build() WorkManager.getInstance(context) .enqueueUniqueWork("offline_upload", ExistingWorkPolicy.REPLACE, uploadWorkRequest) - 自定义
UploadWorker类,在doWork方法中实现上传逻辑,上传完成后删除本地已同步的离线数据即可。系统会在网络恢复时自动触发任务,不需要应用保持运行。
iOS端
iOS系统通过Background Tasks框架实现后台任务调度:
- 首先在Xcode中开启项目的后台模式权限,勾选
Background fetch和Background processing - 在Info.plist中注册自定义的后台任务标识符,例如
com.yourpackage.offline_upload - 应用启动时注册任务调度逻辑:
import BackgroundTasks func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.yourpackage.offline_upload", using: nil) { task in self.handleUploadTask(task: task as! BGAppRefreshTask) } scheduleUploadTask() return true } // 调度上传任务 func scheduleUploadTask() { let request = BGAppRefreshTaskRequest(identifier: "com.yourpackage.offline_upload") request.earliestBeginDate = Date(timeIntervalSinceNow: 1) do { try BGTaskScheduler.shared.submit(request) } catch { print("任务调度失败: \(error)") } } // 执行上传逻辑 func handleUploadTask(task: BGAppRefreshTask) { scheduleUploadTask() // 重新调度下一次任务 task.expirationHandler = { task.setTaskCompleted(success: false) } // 读取本地离线数据完成上传,成功后回调 task.setTaskCompleted(success: true) }
Flutter层简化实现(使用封装库)
可以直接用workmanager库完成双端适配,不需要手写原生代码:
- 先在pubspec.yaml添加依赖:
workmanager: ^0.5.1 - 在main.dart中初始化任务调度:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Workmanager().initialize( callbackDispatcher, isInDebugMode: false, ); // 注册网络可用时触发的上传任务 await Workmanager().registerOneOffTask( "offline-upload-task", "uploadOfflineData", constraints: Constraints( networkType: NetworkType.connected, ), existingWorkPolicy: ExistingWorkPolicy.replace, ); runApp(const MyApp()); } // 回调必须为顶层函数 @pragma('vm:entry-point') void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { if (task == "uploadOfflineData") { // 1. 读取本地未上传的离线数据 // 2. 批量上传到服务端 // 3. 上传成功后删除本地已同步数据 return true; } return false; }); } - 每次用户新增离线数据时,都调用一次
registerOneOffTask方法,确保系统始终有等待触发的上传任务即可。
内容的提问来源于stack exchange,提问作者Kleyson Rios
相关产品推荐
相关产品推荐

