Skip to content

Commit 66c8e46

Browse files
committed
retry starting new threads
Thread.start() can throw OutOfMemoryError errors and we can attempt to start the thread again. App developers can handle onTrimMemory and might be cleaning up memory. While the SDK can't know if this is being done its better to retry then to crash the app. This commit doesn't cover all new thread, just some of the most common ones. Also in v5 most new threads have been migrated to Kotlin coroutines so this patch should not be used outside of this player model branch.
1 parent caf1550 commit 66c8e46

File tree

4 files changed

+37
-14
lines changed

4 files changed

+37
-14
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSBackgroundSync.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
package com.onesignal;
2929

30+
import static com.onesignal.OSUtils.startThreadWithRetry;
31+
3032
import android.app.AlarmManager;
3133
import android.app.PendingIntent;
3234
import android.app.job.JobInfo;
@@ -63,7 +65,7 @@ void doBackgroundSync(Context context, Runnable runnable) {
6365
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "OSBackground sync, calling initWithContext");
6466
OneSignal.initWithContext(context);
6567
syncBgThread = new Thread(runnable, getSyncTaskThreadId());
66-
syncBgThread.start();
68+
startThreadWithRetry(syncBgThread);
6769
}
6870

6971
boolean stopSyncBgThread() {

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,4 +691,18 @@ static Throwable getRootCauseThrowable(@NonNull Throwable subjectThrowable) {
691691
static String getRootCauseMessage(@NonNull Throwable throwable) {
692692
return getRootCauseThrowable(throwable).getMessage();
693693
}
694+
695+
static void startThreadWithRetry(@NonNull Thread thread) {
696+
boolean started = false;
697+
while (!started) {
698+
try {
699+
thread.start();
700+
started = true;
701+
} catch (OutOfMemoryError ignored) {
702+
try {
703+
Thread.sleep(250);
704+
} catch (InterruptedException ignoreInterrupted) {}
705+
}
706+
}
707+
}
694708
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignal.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import static com.onesignal.GenerateNotification.BUNDLE_KEY_ACTION_ID;
7676
import static com.onesignal.GenerateNotification.BUNDLE_KEY_ANDROID_NOTIFICATION_ID;
7777
import static com.onesignal.NotificationBundleProcessor.newJsonArray;
78+
import static com.onesignal.OSUtils.startThreadWithRetry;
7879

7980
/**
8081
* The main OneSignal class - this is where you will interface with the OneSignal SDK
@@ -1488,15 +1489,16 @@ private static void registerUser() {
14881489
return;
14891490
}
14901491

1491-
new Thread(new Runnable() {
1492+
Thread thread = new Thread(new Runnable() {
14921493
public void run() {
14931494
try {
14941495
registerUserTask();
14951496
} catch(JSONException t) {
14961497
Log(LOG_LEVEL.FATAL, "FATAL Error registering device!", t);
14971498
}
14981499
}
1499-
}, "OS_REG_USER").start();
1500+
}, "OS_REG_USER");
1501+
startThreadWithRetry(thread);
15001502
}
15011503

15021504
private static void registerUserTask() throws JSONException {

OneSignalSDK/onesignal/src/main/java/com/onesignal/OneSignalRestClient.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
package com.onesignal;
2929

30+
import static com.onesignal.OSUtils.startThreadWithRetry;
31+
3032
import android.net.TrafficStats;
3133
import android.os.Build;
3234
import androidx.annotation.NonNull;
@@ -65,27 +67,30 @@ private static int getThreadTimeout(int timeout) {
6567
}
6668

6769
public static void put(final String url, final JSONObject jsonBody, final ResponseHandler responseHandler) {
68-
new Thread(new Runnable() {
70+
Thread thread = new Thread(new Runnable() {
6971
public void run() {
7072
makeRequest(url, "PUT", jsonBody, responseHandler, TIMEOUT, null);
7173
}
72-
}, "OS_REST_ASYNC_PUT").start();
74+
}, "OS_REST_ASYNC_PUT");
75+
startThreadWithRetry(thread);
7376
}
7477

7578
public static void post(final String url, final JSONObject jsonBody, final ResponseHandler responseHandler) {
76-
new Thread(new Runnable() {
79+
Thread thread = new Thread(new Runnable() {
7780
public void run() {
7881
makeRequest(url, "POST", jsonBody, responseHandler, TIMEOUT, null);
7982
}
80-
}, "OS_REST_ASYNC_POST").start();
83+
}, "OS_REST_ASYNC_POST");
84+
startThreadWithRetry(thread);
8185
}
8286

8387
public static void get(final String url, final ResponseHandler responseHandler, @NonNull final String cacheKey) {
84-
new Thread(new Runnable() {
88+
Thread thread = new Thread(new Runnable() {
8589
public void run() {
8690
makeRequest(url, null, null, responseHandler, GET_TIMEOUT, cacheKey);
8791
}
88-
}, "OS_REST_ASYNC_GET").start();
92+
}, "OS_REST_ASYNC_GET");
93+
startThreadWithRetry(thread);
8994
}
9095

9196
public static void getSync(final String url, final ResponseHandler responseHandler, @NonNull String cacheKey) {
@@ -114,8 +119,8 @@ public void run() {
114119
callbackThread[0] = startHTTPConnection(url, method, jsonBody, responseHandler, timeout, cacheKey);
115120
}
116121
}, "OS_HTTPConnection");
117-
118-
connectionThread.start();
122+
123+
startThreadWithRetry(connectionThread);
119124

120125
// getResponseCode() can hang past it's timeout setting so join it's thread to ensure it is timing out.
121126
try {
@@ -129,7 +134,7 @@ public void run() {
129134
e.printStackTrace();
130135
}
131136
}
132-
137+
133138
private static Thread startHTTPConnection(String url, String method, JSONObject jsonBody, ResponseHandler responseHandler, int timeout, @Nullable String cacheKey) {
134139
int httpResponse = -1;
135140
HttpURLConnection con = null;
@@ -279,7 +284,7 @@ public void run() {
279284
handler.onSuccess(response);
280285
}
281286
}, "OS_REST_SUCCESS_CALLBACK");
282-
thread.start();
287+
startThreadWithRetry(thread);
283288

284289
return thread;
285290
}
@@ -293,7 +298,7 @@ public void run() {
293298
handler.onFailure(statusCode, response, throwable);
294299
}
295300
}, "OS_REST_FAILURE_CALLBACK");
296-
thread.start();
301+
startThreadWithRetry(thread);
297302

298303
return thread;
299304
}

0 commit comments

Comments
 (0)