面试题答案
一键面试优化SharedPreferences监听机制性能
- 减少不必要监听:
- 仔细分析业务需求,只在真正需要监听
SharedPreferences
变化的地方设置监听。避免在无关紧要的页面或模块中添加监听,减少不必要的回调触发。 - 例如,如果某个页面只在初始化时读取
SharedPreferences
的值,之后并不关心其变化,就不需要为该页面设置监听。
- 仔细分析业务需求,只在真正需要监听
- 合并监听:
- 在多个地方需要监听
SharedPreferences
相同变化的场景下,将这些监听合并为一个。这样可以减少监听的数量,从而降低性能开销。 - 比如,在多个页面都需要监听用户语言设置的变化,可在应用的核心模块统一设置一个监听,然后通过事件总线或自定义通知机制将变化传递给其他需要的页面。
- 在多个地方需要监听
- 防抖处理:
- 当
SharedPreferences
的值频繁变化时,使用防抖策略。在监听到变化后,设置一个短时间的延迟(如200毫秒),如果在这个延迟时间内再次触发变化,就重置延迟时间,只有在延迟时间结束且没有新的变化时,才执行回调逻辑。 - 在Flutter中可以使用
Timer
来实现防抖逻辑,示例代码如下:
Timer? _debounceTimer; void _onSharedPreferencesChange() { if (_debounceTimer!= null) { _debounceTimer!.cancel(); } _debounceTimer = Timer(const Duration(milliseconds: 200), () { // 执行实际的回调逻辑 }); }
- 当
- 异步读取:
- 当读取
SharedPreferences
的值时,使用异步操作,避免阻塞主线程。SharedPreferences
本身的读取方法就是异步的,确保在调用时正确处理异步逻辑。 - 例如:
Future<String?> getSomeValue() async { final prefs = await SharedPreferences.getInstance(); return prefs.getString('some_key'); }
- 当读取
定制新的监听机制
- 基于事件总线:
- 可以使用事件总线库,如
rxdart
的Subject
来实现自定义监听机制。 - 首先,创建一个
BehaviorSubject
来管理SharedPreferences
的变化事件,示例代码如下:
import 'package:rxdart/rxdart.dart'; class SharedPreferencesEventBus { static final SharedPreferencesEventBus _instance = SharedPreferencesEventBus._(); factory SharedPreferencesEventBus() => _instance; final BehaviorSubject<Map<String, dynamic>> _subject = BehaviorSubject<Map<String, dynamic>>(); void emit(Map<String, dynamic> changes) { _subject.add(changes); } Stream<Map<String, dynamic>> get stream => _subject.stream; SharedPreferencesEventBus._(); }
- 然后,在
SharedPreferences
的值发生变化时,通过SharedPreferencesEventBus
的emit
方法发送变化数据。 - 其他需要监听的地方,通过订阅
SharedPreferencesEventBus
的stream
来获取变化通知,如:
SharedPreferencesEventBus().stream.listen((changes) { // 处理变化 });
- 可以使用事件总线库,如
- 基于观察者模式:
- 创建一个
SharedPreferencesObserver
类,包含一个List
来存储观察者。 - 示例代码如下:
class SharedPreferencesObserver { final List<Function(Map<String, dynamic>)> _observers = []; void addObserver(Function(Map<String, dynamic>) observer) { _observers.add(observer); } void removeObserver(Function(Map<String, dynamic>) observer) { _observers.remove(observer); } void notifyObservers(Map<String, dynamic> changes) { for (final observer in _observers) { observer(changes); } } }
- 在
SharedPreferences
值变化时,调用notifyObservers
方法通知所有观察者。 - 观察者通过
addObserver
方法注册监听,如:
final observer = SharedPreferencesObserver(); observer.addObserver((changes) { // 处理变化 });
- 创建一个