From 6372a8e7ea567b9606c72ff4d93bebb471bbe602 Mon Sep 17 00:00:00 2001 From: Rodrigo Martin Date: Thu, 7 May 2020 16:16:40 +0200 Subject: [PATCH] fix(Android): Remove use of AsyncTask.THREAD_POOL_EXECUTOR (#46) --- .../react/tcpsocket/TcpReceiverTask.java | 2 +- .../react/tcpsocket/TcpSocketClient.java | 15 +++++++++++---- .../react/tcpsocket/TcpSocketModule.java | 13 ++++++++----- .../react/tcpsocket/TcpSocketServer.java | 4 +++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpReceiverTask.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpReceiverTask.java index 6b9b782..fdee11f 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpReceiverTask.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpReceiverTask.java @@ -14,7 +14,7 @@ * notifies it's listener when data is received. This is not threadsafe, the listener * should handle synchronicity. */ -public class TcpReceiverTask extends AsyncTask, Void, Void> { +class TcpReceiverTask extends AsyncTask, Void, Void> { /** * An infinite loop to block and read data from the socket. */ diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java index ce259e4..5474bdb 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java @@ -2,17 +2,18 @@ import android.content.Context; import android.net.Network; -import android.os.AsyncTask; import android.util.Pair; import com.facebook.react.bridge.ReadableMap; -import java.io.OutputStream; import java.io.IOException; +import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.security.GeneralSecurityException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.net.SocketFactory; import javax.net.ssl.SSLSocket; @@ -23,12 +24,14 @@ class TcpSocketClient { private final int id; + private final ExecutorService executorService; private TcpReceiverTask receiverTask; private Socket socket; private TcpReceiverTask.OnDataReceivedListener mReceiverListener; TcpSocketClient(final int id) { this.id = id; + this.executorService = Executors.newFixedThreadPool(1); } TcpSocketClient(@NonNull final TcpReceiverTask.OnDataReceivedListener receiverListener, @NonNull final Integer id, @Nullable final Socket socket) { @@ -38,6 +41,9 @@ class TcpSocketClient { mReceiverListener = receiverListener; } + ExecutorService getExecutorService() { + return this.executorService; + } public int getId() { return id; @@ -52,7 +58,7 @@ public void connect(@NonNull final Context context, @NonNull final String addres final boolean isTls = options.hasKey("tls") && options.getBoolean("tls"); if (isTls) { SocketFactory sf; - if (options.hasKey("tlsCheckValidity") && !options.getBoolean("tlsCheckValidity")){ + if (options.hasKey("tlsCheckValidity") && !options.getBoolean("tlsCheckValidity")) { sf = SSLCertificateHelper.createBlindSocketFactory(); } else { final String customTlsCert = options.hasKey("tlsCert") ? options.getString("tlsCert") : null; @@ -89,7 +95,7 @@ public void connect(@NonNull final Context context, @NonNull final String addres @SuppressWarnings("WeakerAccess") public void startListening() { //noinspection unchecked - receiverTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Pair<>(this, mReceiverListener)); + receiverTask.executeOnExecutor(getExecutorService(), new Pair<>(this, mReceiverListener)); } /** @@ -113,6 +119,7 @@ public void close() { if (receiverTask != null && !receiverTask.isCancelled()) { // stop the receiving task receiverTask.cancel(true); + getExecutorService().shutdown(); } // close the socket if (socket != null && !socket.isClosed()) { diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java index abbccca..b6f6fae 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java @@ -6,7 +6,6 @@ import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkRequest; -import android.os.AsyncTask; import android.util.Base64; import android.net.Network; @@ -26,6 +25,8 @@ import java.net.InetSocketAddress; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -34,10 +35,12 @@ public class TcpSocketModule extends ReactContextBaseJavaModule implements TcpReceiverTask.OnDataReceivedListener { private static final String TAG = "TcpSockets"; + private static final int N_THREADS = 2; private final ReactApplicationContext mReactContext; private final ConcurrentHashMap socketClients = new ConcurrentHashMap<>(); private final ConcurrentHashMap mNetworkMap = new ConcurrentHashMap<>(); private final CurrentNetwork currentNetwork = new CurrentNetwork(); + private final ExecutorService executorService = Executors.newFixedThreadPool(N_THREADS); public TcpSocketModule(ReactApplicationContext reactContext) { super(reactContext); @@ -89,7 +92,7 @@ protected void doInBackgroundGuarded(Void... params) { onError(cId, e.getMessage()); } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }.executeOnExecutor(executorService); } @SuppressLint("StaticFieldLeak") @@ -115,7 +118,7 @@ protected void doInBackgroundGuarded(Void... params) { onError(cId, e.toString()); } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }.executeOnExecutor(executorService); } @SuppressLint("StaticFieldLeak") @@ -132,7 +135,7 @@ protected void doInBackgroundGuarded(Void... params) { socketClient.close(); socketClients.remove(cId); } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }.executeOnExecutor(executorService); } @SuppressWarnings("unused") @@ -158,7 +161,7 @@ protected void doInBackgroundGuarded(Void... params) { onError(cId, uhe.getMessage()); } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }.executeOnExecutor(executorService); } private void requestNetwork(final int transportType) throws InterruptedException { diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketServer.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketServer.java index 9d3f78b..43d970a 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketServer.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketServer.java @@ -11,6 +11,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; public final class TcpSocketServer extends TcpSocketClient { private ServerSocket serverSocket; @@ -76,7 +77,7 @@ private int getClientId() { private void listen() { //noinspection unchecked - listening.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + listening.executeOnExecutor(getExecutorService()); } @Override @@ -90,6 +91,7 @@ public void close() { if (!listening.isCancelled()) { // stop the receiving task listening.cancel(true); + getExecutorService().shutdown(); } // close the socket