diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/storage/AsyncStorageModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/storage/AsyncStorageModule.java index c9fc96e575f169..d51e13b23e3db5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/storage/AsyncStorageModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/storage/AsyncStorageModule.java @@ -7,10 +7,13 @@ package com.facebook.react.modules.storage; +import java.util.ArrayDeque; import java.util.HashSet; +import java.util.concurrent.Executor; import android.database.Cursor; import android.database.sqlite.SQLiteStatement; +import android.os.AsyncTask; import com.facebook.common.logging.FLog; import com.facebook.react.bridge.Arguments; @@ -43,6 +46,33 @@ public final class AsyncStorageModule private ReactDatabaseSupplier mReactDatabaseSupplier; private boolean mShuttingDown = false; + // Borrowed from https://android.googlesource.com/platform/frameworks/base.git/+/1488a3a19d4681a41fb45570c15e14d99db1cb66/core/java/android/os/AsyncTask.java#237 + private static class SerialExecutor implements Executor { + final ArrayDeque mTasks = new ArrayDeque(); + Runnable mActive; + public synchronized void execute(final Runnable r) { + mTasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + scheduleNext(); + } + } + }); + if (mActive == null) { + scheduleNext(); + } + } + protected synchronized void scheduleNext() { + if ((mActive = mTasks.poll()) != null) { + AsyncTask.THREAD_POOL_EXECUTOR.execute(mActive); + } + } + } + + private static final Executor ASYNC_STORAGE_EXECUTOR = new SerialExecutor(); + public AsyncStorageModule(ReactApplicationContext reactContext) { super(reactContext); mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(reactContext); @@ -141,7 +171,7 @@ protected void doInBackgroundGuarded(Void... params) { callback.invoke(null, data); } - }.execute(); + }.executeOnExecutor(ASYNC_STORAGE_EXECUTOR); } /** @@ -208,7 +238,7 @@ protected void doInBackgroundGuarded(Void... params) { callback.invoke(); } } - }.execute(); + }.executeOnExecutor(ASYNC_STORAGE_EXECUTOR); } /** @@ -259,7 +289,7 @@ protected void doInBackgroundGuarded(Void... params) { callback.invoke(); } } - }.execute(); + }.executeOnExecutor(ASYNC_STORAGE_EXECUTOR); } /** @@ -322,7 +352,7 @@ protected void doInBackgroundGuarded(Void... params) { callback.invoke(); } } - }.execute(); + }.executeOnExecutor(ASYNC_STORAGE_EXECUTOR); } /** @@ -345,7 +375,7 @@ protected void doInBackgroundGuarded(Void... params) { callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage())); } } - }.execute(); + }.executeOnExecutor(ASYNC_STORAGE_EXECUTOR); } /** @@ -379,7 +409,7 @@ protected void doInBackgroundGuarded(Void... params) { } callback.invoke(null, data); } - }.execute(); + }.executeOnExecutor(ASYNC_STORAGE_EXECUTOR); } /**