You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 02:39:03