diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 1516163b8807..b0899d57a3c5 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.4 + +* Fix a regression with simultaneous writes on Android. + ## 2.0.3 * Android: don't create additional Handler when method channel is called. diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 4f55d882005f..4486421e3959 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -53,7 +53,7 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { MethodCallHandlerImpl(Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); executor = - new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue()); + new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue()); handler = new Handler(Looper.getMainLooper()); } diff --git a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart index 1caf695d9365..d36286a559b3 100644 --- a/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences/example/integration_test/shared_preferences_test.dart @@ -91,5 +91,18 @@ void main() { expect(preferences.getDouble('double'), null); expect(preferences.getStringList('List'), null); }); + + testWidgets('simultaneous writes', (WidgetTester _) async { + final List> writes = >[]; + final int writeCount = 100; + for (int i = 1; i <= writeCount; i++) { + writes.add(preferences.setInt('int', i)); + } + List result = await Future.wait(writes, eagerError: true); + // All writes should succeed. + expect(result.where((element) => !element), isEmpty); + // The last write should win. + expect(preferences.getInt('int'), writeCount); + }); }); } diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 899266a4d6f0..b53bbfd93a38 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 2.0.3 +version: 2.0.4 flutter: plugin: