diff --git a/packages/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/lib/shared_preferences.dart index d013484fa1ad..aece19b6e29e 100644 --- a/packages/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/lib/shared_preferences.dart @@ -18,14 +18,24 @@ class SharedPreferences { SharedPreferences._(this._preferenceCache); static const String _prefix = 'flutter.'; - static SharedPreferences _instance; + static Completer _completer; static Future getInstance() async { - if (_instance == null) { - final Map preferencesMap = - await _getSharedPreferencesMap(); - _instance = SharedPreferences._(preferencesMap); + if (_completer == null) { + _completer = Completer(); + try { + final Map preferencesMap = + await _getSharedPreferencesMap(); + _completer.complete(SharedPreferences._(preferencesMap)); + } on Exception catch (e) { + // If there's an error, explicitly return the future with an error. + // then set the completer to null so we can retry. + _completer.completeError(e); + final Future sharedPrefsFuture = _completer.future; + _completer = null; + return sharedPrefsFuture; + } } - return _instance; + return _completer.future; } /// The cache that holds all preferences. @@ -168,7 +178,7 @@ class SharedPreferences { /// Initializes the shared preferences with mock values for testing. /// - /// If the singleton instance has been initialized already, it is automatically reloaded. + /// If the singleton instance has been initialized already, it is nullified. @visibleForTesting static void setMockInitialValues(Map values) { _kChannel.setMockMethodCallHandler((MethodCall methodCall) async { @@ -177,6 +187,6 @@ class SharedPreferences { } return null; }); - _instance?.reload(); + _completer = null; } } diff --git a/packages/shared_preferences/test/shared_preferences_test.dart b/packages/shared_preferences/test/shared_preferences_test.dart index f9f4bde06ba3..c0d9068204c9 100755 --- a/packages/shared_preferences/test/shared_preferences_test.dart +++ b/packages/shared_preferences/test/shared_preferences_test.dart @@ -155,6 +155,12 @@ void main() { expect(preferences.getString('String'), kTestValues2['flutter.String']); }); + test('back to back calls should return same instance.', () async { + final Future first = SharedPreferences.getInstance(); + final Future second = SharedPreferences.getInstance(); + expect(await first, await second); + }); + group('mocking', () { const String _key = 'dummy'; const String _prefixedKey = 'flutter.' + _key;