MST

星途 面试题库

面试题:Flutter中SharedPreferences性能优化及并发处理

在一个频繁读写SharedPreferences的Flutter应用场景下,可能会遇到性能问题和并发冲突,你会采取哪些策略来优化性能并解决并发问题?
18.1万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

性能优化策略

  1. 批量操作
    • 尽量避免每次只对 SharedPreferences 进行单个数据的读写。例如,如果需要更新多个键值对,将它们合并在一次 SharedPreferences 的写入操作中。
    final prefs = await SharedPreferences.getInstance();
    prefs.setString('key1', 'value1');
    prefs.setString('key2', 'value2');
    prefs.commit();
    
  2. 缓存数据
    • 在内存中缓存从 SharedPreferences 读取的数据。当应用频繁读取相同的数据时,先从内存缓存中获取,如果缓存中没有再从 SharedPreferences 读取,并更新缓存。
    Map<String, dynamic> memoryCache = {};
    Future<dynamic> getValueFromCacheOrPrefs(String key) async {
      if (memoryCache.containsKey(key)) {
        return memoryCache[key];
      }
      final prefs = await SharedPreferences.getInstance();
      final value = prefs.get(key);
      memoryCache[key] = value;
      return value;
    }
    
  3. 异步加载
    • 在应用启动时,使用 Future 异步加载 SharedPreferences 数据,避免阻塞主线程。
    Future<void> loadPrefsOnStartup() async {
      final prefs = await SharedPreferences.getInstance();
      // 在这里可以处理从prefs读取的数据
    }
    

解决并发问题策略

  1. 锁机制
    • 使用 Lock 类(如 dart:async 中的 Lock)来控制对 SharedPreferences 的并发访问。在进行读写操作前获取锁,操作完成后释放锁。
    import 'dart:async';
    final lock = Lock();
    Future<void> writeToSharedPrefs(String key, String value) async {
      await lock.synchronized(() async {
        final prefs = await SharedPreferences.getInstance();
        prefs.setString(key, value);
        prefs.commit();
      });
    }
    
  2. 单例模式
    • 创建一个 SharedPreferences 单例类,确保在整个应用中只有一个实例进行读写操作,减少并发冲突的可能性。
    class SharedPrefsSingleton {
      static SharedPrefsSingleton? _instance;
      static Future<SharedPrefsSingleton> getInstance() async {
        if (_instance == null) {
          final prefs = await SharedPreferences.getInstance();
          _instance = SharedPrefsSingleton._(prefs);
        }
        return _instance!;
      }
      final SharedPreferences _prefs;
      SharedPrefsSingleton._(this._prefs);
      Future<void> write(String key, String value) async {
        _prefs.setString(key, value);
        _prefs.commit();
      }
      Future<String?> read(String key) async {
        return _prefs.getString(key);
      }
    }