面试题答案
一键面试优化频繁使用SharedPreferences性能的措施
- 批量操作
- 避免多次单个数据的读写。例如,当需要存储多个配置项时,先将所有数据整理成一个Map,然后使用
SharedPreferences
的setValues
方法(如果有类似方法,SharedPreferences
通常使用put
系列方法,这里假设可批量操作方式)一次性写入。 - 读取时也尽量批量读取相关联的数据,减少读取次数。
- 避免多次单个数据的读写。例如,当需要存储多个配置项时,先将所有数据整理成一个Map,然后使用
- 缓存策略
- 在内存中创建一个缓存。例如,在应用启动时读取
SharedPreferences
中的常用数据并缓存到内存变量中。当应用内需要读取这些数据时,优先从内存缓存中获取,只有在缓存数据不存在或过期时,才从SharedPreferences
读取,然后更新缓存。 - 对于缓存数据设置合理的过期时间,确保数据的实时性。比如一些用户配置信息,如果很少改变,可以设置较长的过期时间;而一些与服务器交互相关的配置,过期时间可设置短一些。
- 在内存中创建一个缓存。例如,在应用启动时读取
- 异步处理
- 使用
async
和await
关键字将SharedPreferences
的读写操作放在异步任务中执行,避免阻塞主线程。例如:
Future<void> saveData() async { final prefs = await SharedPreferences.getInstance(); await prefs.setString('key', 'value'); }
- 这样在进行数据存储时,主线程可以继续处理其他UI相关的任务,提高应用的响应速度。
- 使用
保证多线程或异步操作数据一致性的方法
- 锁机制
- 使用
Lock
类(在Dart中可使用dart:async
库中的Lock
)。例如,在对SharedPreferences
进行读写操作前,先获取锁:
final lock = Lock(); Future<void> readData() async { await lock.synchronized(() async { final prefs = await SharedPreferences.getInstance(); return prefs.getString('key'); }); }
- 这样在同一时间只有一个异步操作能够获取锁并访问
SharedPreferences
,避免了多个操作同时读写导致的数据不一致。
- 使用
- 事务处理(如果支持)
- 如果
SharedPreferences
支持事务(实际上SharedPreferences
本身没有传统数据库那种事务概念,但可以模仿其思想),将多个相关的读写操作封装在一个事务中。 - 例如,先读取数据,根据数据进行一些计算,然后再写入新数据,将这一系列操作视为一个原子操作,要么全部成功,要么全部失败。如果
SharedPreferences
不直接支持事务,可以通过额外的状态标记变量来实现类似功能。在操作开始前设置一个状态变量表示正在操作,操作完成后清除该标记,在每次操作前检查该标记,如果正在操作则等待。
- 如果
- 版本控制
- 在
SharedPreferences
中存储数据时,同时存储一个版本号。每次读取数据时,先读取版本号。 - 当有异步操作要修改数据时,先读取当前版本号,在修改完成后更新版本号。其他异步操作在读取数据时,如果发现版本号变化,重新读取数据,以保证获取到最新数据。
- 在