Flutter 离线缓存与同步机制实现指南

一、核心架构设计
class SyncSystem {
  final LocalCache localCache;
  final RemoteApi remoteApi;
  final SyncConflictResolver conflictResolver;

  // 同步状态机
  SyncStatus _status = SyncStatus.idle;
  
  Future<void> executeSync() async {
    if (_status == Syncing) return;
    _status = Syncing;
    
    try {
      // 1. 获取本地待同步数据
      final localChanges = await localCache.getPendingChanges();
      
      // 2. 获取服务器最新状态
      final serverState = await remoteApi.fetchLatest();
      
      // 3. 冲突检测与解决
      final resolvedData = conflictResolver.resolve(
        local: localChanges,
        remote: serverState
      );
      
      // 4. 双向同步
      await Future.wait([
        localCache.commitChanges(resolvedData),
        remoteApi.pushChanges(resolvedData)
      ]);
      
      // 5. 更新同步元数据
      await localCache.updateSyncTimestamp();
      
    } catch (e) {
      // 错误处理
    } finally {
      _status = Idle;
    }
  }
}

二、关键技术实现
  1. 本地存储方案
class HiveCache {
  final Box _box;
  static const _syncKey = 'last_sync';
  
  Future<List<DataModel>> getPendingChanges() async {
    return _box.values
      .where((item) => item.isDirty)
      .toList();
  }
  
  Future<void> updateSyncTimestamp() async {
    await _box.put(_syncKey, DateTime.now().millisecondsSinceEpoch);
  }
}

  1. 冲突解决策略
class TimestampConflictResolver {
  DataModel resolve({required DataModel local, required DataModel remote}) {
    // 时间戳比较算法
    final localModified = local.updatedAt;
    final remoteModified = remote.updatedAt;
    
    return (localModified.isAfter(remoteModified)) 
        ? local..mergeWith(remote)
        : remote..mergeWith(local);
  }
}

  1. 网络状态感知
class ConnectivityWatcher {
  final StreamController<bool> _controller = StreamController.broadcast();
  
  void init() {
    Connectivity().onConnectivityChanged.listen((result) {
      _controller.add(result != ConnectivityResult.none);
    });
  }
  
  Stream<bool> get connectionStream => _controller.stream;
}

三、同步流程优化
  1. 增量同步算法
Future<SyncPayload> fetchChangesSince(DateTime lastSync) async {
  final query = '''
    SELECT * FROM items 
    WHERE updated_at > ${lastSync.millisecondsSinceEpoch}
  ''';
  return await db.rawQuery(query);
}

  1. 操作队列管理
class SyncQueue {
  final List<SyncOperation> _queue = [];
  bool _isProcessing = false;
  
  void enqueue(SyncOperation op) {
    _queue.add(op);
    _processNext();
  }
  
  void _processNext() async {
    if (_isProcessing || _queue.isEmpty) return;
    
    _isProcessing = true;
    final operation = _queue.removeAt(0);
    
    try {
      await operation.execute();
    } finally {
      _isProcessing = false;
      _processNext();
    }
  }
}

四、性能优化策略
  1. 数据分块传输
Future<void> pushLargeData(List<DataModel> data) async {
  const chunkSize = 50;
  for (var i = 0; i < data.length; i += chunkSize) {
    final chunk = data.sublist(i, min(i + chunkSize, data.length));
    await remoteApi.pushChunk(chunk);
  }
}

  1. 本地缓存清理
Future<void> purgeOldData() async {
  final threshold = DateTime.now().subtract(const Duration(days: 30));
  await _box.deleteAll(
    _box.keys.where((key) => 
      _box.get(key).lastAccess.isBefore(threshold)
    )
  );
}

五、完整实现示例
// 主业务逻辑
class DataService {
  final HiveCache cache;
  final ApiClient api;
  final SyncSystem syncSystem;
  
  Future<DataModel> fetchData(String id) async {
    // 离线优先策略
    try {
      final remoteData = await api.fetch(id);
      await cache.save(remoteData);
      return remoteData;
    } on SocketException {
      return cache.get(id);
    }
  }
  
  Future<void> updateData(DataModel newData) async {
    // 标记为待同步状态
    await cache.save(newData..isDirty = true);
    syncSystem.enqueueSync();
  }
}

六、最佳实践建议
  1. 同步频率控制:使用指数退避算法处理失败请求
  2. 数据压缩:传输前使用gzip压缩JSON数据
  3. 安全机制:同步操作需携带用户认证令牌
  4. 监控指标:记录同步成功率、冲突率等关键指标
  5. 单元测试:重点测试冲突解决和网络切换场景

实现要点:采用离线优先设计哲学,确保核心功能在无网络时可用。冲突解决推荐使用混合策略:时间戳解决基础冲突,重要数据保留冲突记录供用户决策。同步操作应设计为等幂操作,支持重复执行不产生副作用。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐