diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSBackgroundSync.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSBackgroundSync.java index e658e80901..b87a4aa86b 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSBackgroundSync.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSBackgroundSync.java @@ -27,6 +27,8 @@ package com.onesignal; +import static com.onesignal.OSUtils.startThreadWithRetry; + import android.app.AlarmManager; import android.app.PendingIntent; import android.app.job.JobInfo; @@ -63,7 +65,7 @@ void doBackgroundSync(Context context, Runnable runnable) { OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "OSBackground sync, calling initWithContext"); OneSignal.initWithContext(context); syncBgThread = new Thread(runnable, getSyncTaskThreadId()); - syncBgThread.start(); + startThreadWithRetry(syncBgThread); } boolean stopSyncBgThread() { diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java index 8e4483315f..62b6e7f428 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java @@ -691,4 +691,18 @@ static Throwable getRootCauseThrowable(@NonNull Throwable subjectThrowable) { static String getRootCauseMessage(@NonNull Throwable throwable) { return getRootCauseThrowable(throwable).getMessage(); } + + static void startThreadWithRetry(@NonNull Thread thread) { + boolean started = false; + while (!started) { + try { + thread.start(); + started = true; + } catch (OutOfMemoryError ignored) { + try { + Thread.sleep(250); + } catch (InterruptedException ignoreInterrupted) {} + } + } + } } diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java index 051f3ebf68..25bb6c3fbe 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java @@ -75,6 +75,7 @@ import static com.onesignal.GenerateNotification.BUNDLE_KEY_ACTION_ID; import static com.onesignal.GenerateNotification.BUNDLE_KEY_ANDROID_NOTIFICATION_ID; import static com.onesignal.NotificationBundleProcessor.newJsonArray; +import static com.onesignal.OSUtils.startThreadWithRetry; /** * The main OneSignal class - this is where you will interface with the OneSignal SDK @@ -1488,7 +1489,7 @@ private static void registerUser() { return; } - new Thread(new Runnable() { + Thread thread = new Thread(new Runnable() { public void run() { try { registerUserTask(); @@ -1496,7 +1497,8 @@ public void run() { Log(LOG_LEVEL.FATAL, "FATAL Error registering device!", t); } } - }, "OS_REG_USER").start(); + }, "OS_REG_USER"); + startThreadWithRetry(thread); } private static void registerUserTask() throws JSONException { diff --git a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalRestClient.java b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalRestClient.java index eb113d2eb4..462c852b48 100644 --- a/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalRestClient.java +++ b/OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalRestClient.java @@ -27,6 +27,8 @@ package com.onesignal; +import static com.onesignal.OSUtils.startThreadWithRetry; + import android.net.TrafficStats; import android.os.Build; import androidx.annotation.NonNull; @@ -65,27 +67,30 @@ private static int getThreadTimeout(int timeout) { } public static void put(final String url, final JSONObject jsonBody, final ResponseHandler responseHandler) { - new Thread(new Runnable() { + Thread thread = new Thread(new Runnable() { public void run() { makeRequest(url, "PUT", jsonBody, responseHandler, TIMEOUT, null); } - }, "OS_REST_ASYNC_PUT").start(); + }, "OS_REST_ASYNC_PUT"); + startThreadWithRetry(thread); } public static void post(final String url, final JSONObject jsonBody, final ResponseHandler responseHandler) { - new Thread(new Runnable() { + Thread thread = new Thread(new Runnable() { public void run() { makeRequest(url, "POST", jsonBody, responseHandler, TIMEOUT, null); } - }, "OS_REST_ASYNC_POST").start(); + }, "OS_REST_ASYNC_POST"); + startThreadWithRetry(thread); } public static void get(final String url, final ResponseHandler responseHandler, @NonNull final String cacheKey) { - new Thread(new Runnable() { + Thread thread = new Thread(new Runnable() { public void run() { makeRequest(url, null, null, responseHandler, GET_TIMEOUT, cacheKey); } - }, "OS_REST_ASYNC_GET").start(); + }, "OS_REST_ASYNC_GET"); + startThreadWithRetry(thread); } public static void getSync(final String url, final ResponseHandler responseHandler, @NonNull String cacheKey) { @@ -114,8 +119,8 @@ public void run() { callbackThread[0] = startHTTPConnection(url, method, jsonBody, responseHandler, timeout, cacheKey); } }, "OS_HTTPConnection"); - - connectionThread.start(); + + startThreadWithRetry(connectionThread); // getResponseCode() can hang past it's timeout setting so join it's thread to ensure it is timing out. try { @@ -129,7 +134,7 @@ public void run() { e.printStackTrace(); } } - + private static Thread startHTTPConnection(String url, String method, JSONObject jsonBody, ResponseHandler responseHandler, int timeout, @Nullable String cacheKey) { int httpResponse = -1; HttpURLConnection con = null; @@ -279,7 +284,7 @@ public void run() { handler.onSuccess(response); } }, "OS_REST_SUCCESS_CALLBACK"); - thread.start(); + startThreadWithRetry(thread); return thread; } @@ -293,7 +298,7 @@ public void run() { handler.onFailure(statusCode, response, throwable); } }, "OS_REST_FAILURE_CALLBACK"); - thread.start(); + startThreadWithRetry(thread); return thread; }