From afd1c029f6868a17ded3f3c8c3674a09e0504794 Mon Sep 17 00:00:00 2001 From: Ruby Hartono <58564005+rh-id@users.noreply.github.com> Date: Wed, 2 Dec 2020 00:14:46 +0700 Subject: [PATCH 1/4] Replace AsyncTask class with AsyncHandler to handle async task --- .../sharedpreferences/AsyncHandler.java | 66 +++++++++++++++++++ .../MethodCallHandlerImpl.java | 29 ++++---- 2 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java new file mode 100644 index 000000000000..a1a5d61daea8 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java @@ -0,0 +1,66 @@ +package io.flutter.plugins.sharedpreferences; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +/** + * Helper class to handle async tasks + */ +class AsyncHandler { + private ExecutorService executorService; + + private final Handler handler; + + public AsyncHandler() { + // Replace this executor when there is somehow a way in the future + // to inject from plugin engine or application + executorService = Executors.newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r, "SharedPreferencesAsync"); + thread.setDaemon(true); + return null; + } + }); + handler = new Handler(Looper.getMainLooper()); + } + + public void executeAsync(final Callable executeInBackground, final Callback resultCallback) { + executorService.execute(new Runnable() { + @Override + public void run() { + try { + final R result = executeInBackground.call(); + handler.post(new Runnable() { + @Override + public void run() { + resultCallback.onComplete(result); + } + }); + } catch (final Exception ex) { + handler.post(new Runnable() { + @Override + public void run() { + resultCallback.onError(ex); + } + }); + } + } + }); + } + + public interface Callback { + void onError(Exception e); + + void onComplete(R result); + } + + public interface Callable { + + V call() throws Exception; + } +} 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 33f2474592fa..30ea8aec6c77 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 @@ -6,7 +6,6 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.util.Base64; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -38,12 +37,15 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { private final android.content.SharedPreferences preferences; + private final AsyncHandler asyncHandler; + /** * Constructs a {@link MethodCallHandlerImpl} instance. Creates a {@link * android.content.SharedPreferences} based on the {@code context}. */ MethodCallHandlerImpl(Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + asyncHandler = new AsyncHandler(); } @Override @@ -118,17 +120,22 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { private void commitAsync( final SharedPreferences.Editor editor, final MethodChannel.Result result) { - new AsyncTask() { - @Override - protected Boolean doInBackground(Void... voids) { - return editor.commit(); - } + asyncHandler.executeAsync(new AsyncHandler.Callable() { + @Override + public Boolean call() { + return editor.commit(); + } + }, new AsyncHandler.Callback() { + @Override + public void onError(Exception e) { + result.error(e.getClass().getName(), e.getLocalizedMessage(), e.getMessage()); + } - @Override - protected void onPostExecute(Boolean value) { - result.success(value); - } - }.execute(); + @Override + public void onComplete(Boolean resultValue) { + result.success(resultValue); + } + }); } private List decodeList(String encodedList) throws IOException { From 1920b85b6a06c2ff3736e1ef7038b53520352aa2 Mon Sep 17 00:00:00 2001 From: Ruby Hartono <58564005+rh-id@users.noreply.github.com> Date: Wed, 2 Dec 2020 08:02:47 +0700 Subject: [PATCH 2/4] Format source code --- .../sharedpreferences/AsyncHandler.java | 91 ++++++++++--------- .../MethodCallHandlerImpl.java | 14 +-- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java index a1a5d61daea8..fcb07ea1e04d 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java @@ -2,65 +2,68 @@ import android.os.Handler; import android.os.Looper; - import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; -/** - * Helper class to handle async tasks - */ +/** Helper class to handle async tasks */ class AsyncHandler { - private ExecutorService executorService; + private ExecutorService executorService; - private final Handler handler; + private final Handler handler; - public AsyncHandler() { - // Replace this executor when there is somehow a way in the future - // to inject from plugin engine or application - executorService = Executors.newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { + public AsyncHandler() { + // Replace this executor when there is somehow a way in the future + // to inject from plugin engine or application + executorService = + Executors.newSingleThreadExecutor( + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { Thread thread = new Thread(r, "SharedPreferencesAsync"); thread.setDaemon(true); return null; - } - }); - handler = new Handler(Looper.getMainLooper()); - } + } + }); + handler = new Handler(Looper.getMainLooper()); + } - public void executeAsync(final Callable executeInBackground, final Callback resultCallback) { - executorService.execute(new Runnable() { - @Override - public void run() { - try { - final R result = executeInBackground.call(); - handler.post(new Runnable() { - @Override - public void run() { - resultCallback.onComplete(result); - } - }); - } catch (final Exception ex) { - handler.post(new Runnable() { - @Override - public void run() { - resultCallback.onError(ex); - } - }); - } + public void executeAsync( + final Callable executeInBackground, final Callback resultCallback) { + executorService.execute( + new Runnable() { + @Override + public void run() { + try { + final R result = executeInBackground.call(); + handler.post( + new Runnable() { + @Override + public void run() { + resultCallback.onComplete(result); + } + }); + } catch (final Exception ex) { + handler.post( + new Runnable() { + @Override + public void run() { + resultCallback.onError(ex); + } + }); } + } }); - } + } - public interface Callback { - void onError(Exception e); + public interface Callback { + void onError(Exception e); - void onComplete(R result); - } + void onComplete(R result); + } - public interface Callable { + public interface Callable { - V call() throws Exception; - } + V call() throws Exception; + } } 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 30ea8aec6c77..b3ae51fda223 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 @@ -120,22 +120,24 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { private void commitAsync( final SharedPreferences.Editor editor, final MethodChannel.Result result) { - asyncHandler.executeAsync(new AsyncHandler.Callable() { + asyncHandler.executeAsync( + new AsyncHandler.Callable() { @Override public Boolean call() { - return editor.commit(); + return editor.commit(); } - }, new AsyncHandler.Callback() { + }, + new AsyncHandler.Callback() { @Override public void onError(Exception e) { - result.error(e.getClass().getName(), e.getLocalizedMessage(), e.getMessage()); + result.error(e.getClass().getName(), e.getLocalizedMessage(), e.getMessage()); } @Override public void onComplete(Boolean resultValue) { - result.success(resultValue); + result.success(resultValue); } - }); + }); } private List decodeList(String encodedList) throws IOException { From 196e296317b82e05d3e93f36b7059c2551bf2e44 Mon Sep 17 00:00:00 2001 From: Ruby Hartono <58564005+rh-id@users.noreply.github.com> Date: Thu, 14 Jan 2021 11:17:04 +0700 Subject: [PATCH 3/4] Use ServiceLoader for ExecutorService injection --- .../sharedpreferences/AsyncHandler.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java index fcb07ea1e04d..42f287d2c13b 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java @@ -2,6 +2,8 @@ import android.os.Handler; import android.os.Looper; +import java.util.Iterator; +import java.util.ServiceLoader; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -13,18 +15,22 @@ class AsyncHandler { private final Handler handler; public AsyncHandler() { - // Replace this executor when there is somehow a way in the future - // to inject from plugin engine or application - executorService = - Executors.newSingleThreadExecutor( - new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r, "SharedPreferencesAsync"); - thread.setDaemon(true); - return null; - } - }); + Iterator executorServiceIterator = + ServiceLoader.load(ExecutorService.class).iterator(); + if (executorServiceIterator.hasNext()) { + executorService = executorServiceIterator.next(); + } else { + executorService = + Executors.newSingleThreadExecutor( + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r, "SharedPreferencesAsync"); + thread.setDaemon(true); + return null; + } + }); + } handler = new Handler(Looper.getMainLooper()); } From fdf94d1a719dcc996449d84b6f56051313abd14f Mon Sep 17 00:00:00 2001 From: Ruby Hartono <58564005+rh-id@users.noreply.github.com> Date: Tue, 23 Feb 2021 20:11:46 +0700 Subject: [PATCH 4/4] Fix thread return null on default ThreadFactory --- .../java/io/flutter/plugins/sharedpreferences/AsyncHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java index 42f287d2c13b..21df8197da37 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/AsyncHandler.java @@ -27,7 +27,7 @@ public AsyncHandler() { public Thread newThread(Runnable r) { Thread thread = new Thread(r, "SharedPreferencesAsync"); thread.setDaemon(true); - return null; + return thread; } }); }