Skip to content

Commit 51f1399

Browse files
committed
fix crash with WorkManager helper for initialization
* Before using WorkManager, check for its existence. Else, in rare cases that were crashing, initialize it ourselves. * Provides a method to check if WorkManager is initialized in this process. - This is effectively the `WorkManager.isInitialized()` public method introduced in `androidx.work:work-*:2.8.0-alpha02`. - Please see https://android-review.googlesource.com/c/platform/frameworks/support/+/1941186 for the library's implementation
1 parent a9e796e commit 51f1399

File tree

5 files changed

+76
-10
lines changed

5 files changed

+76
-10
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSFocusHandler.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import androidx.work.Constraints
3232
import androidx.work.ExistingWorkPolicy
3333
import androidx.work.NetworkType
3434
import androidx.work.OneTimeWorkRequest
35-
import androidx.work.WorkManager
3635
import androidx.work.Worker
3736
import androidx.work.WorkerParameters
3837
import java.util.concurrent.TimeUnit
@@ -87,7 +86,8 @@ class OSFocusHandler {
8786
.setInitialDelay(delay, TimeUnit.MILLISECONDS)
8887
.addTag(tag)
8988
.build()
90-
WorkManager.getInstance(context)
89+
90+
OSWorkManagerHelper.getInstance(context)
9191
.enqueueUniqueWork(
9292
tag,
9393
ExistingWorkPolicy.KEEP,
@@ -96,7 +96,7 @@ class OSFocusHandler {
9696
}
9797

9898
fun cancelOnLostFocusWorker(tag: String, context: Context) {
99-
WorkManager.getInstance(context).cancelAllWorkByTag(tag)
99+
OSWorkManagerHelper.getInstance(context).cancelAllWorkByTag(tag)
100100
}
101101

102102
private fun resetStopState() {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import androidx.annotation.NonNull;
1010
import androidx.work.ExistingWorkPolicy;
1111
import androidx.work.OneTimeWorkRequest;
12-
import androidx.work.WorkManager;
1312
import androidx.work.Worker;
1413
import androidx.work.WorkerParameters;
1514

@@ -45,7 +44,7 @@ public static void beginEnqueueingWork(Context context, boolean shouldDelay) {
4544
.setInitialDelay(restoreDelayInSeconds, TimeUnit.SECONDS)
4645
.build();
4746

48-
WorkManager.getInstance(context)
47+
OSWorkManagerHelper.getInstance(context)
4948
.enqueueUniqueWork(NOTIFICATION_RESTORE_WORKER_IDENTIFIER, ExistingWorkPolicy.KEEP, workRequest);
5049
}
5150

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import androidx.work.Data;
77
import androidx.work.ExistingWorkPolicy;
88
import androidx.work.OneTimeWorkRequest;
9-
import androidx.work.WorkManager;
109
import androidx.work.Worker;
1110
import androidx.work.WorkerParameters;
1211

@@ -63,8 +62,9 @@ static void beginEnqueueingWork(Context context, String osNotificationId, int an
6362
.build();
6463

6564
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "OSNotificationWorkManager enqueueing notification work with notificationId: " + osNotificationId + " and jsonPayload: " + jsonPayload);
66-
WorkManager.getInstance(context)
67-
.enqueueUniqueWork(osNotificationId, ExistingWorkPolicy.KEEP, workRequest);
65+
66+
OSWorkManagerHelper.getInstance(context).
67+
enqueueUniqueWork(osNotificationId, ExistingWorkPolicy.KEEP, workRequest);
6868
}
6969

7070
public static class NotificationWorker extends Worker {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import androidx.work.ExistingWorkPolicy;
3636
import androidx.work.NetworkType;
3737
import androidx.work.OneTimeWorkRequest;
38-
import androidx.work.WorkManager;
3938
import androidx.work.Worker;
4039
import androidx.work.WorkerParameters;
4140

@@ -82,7 +81,7 @@ void beginEnqueueingWork(Context context, String osNotificationId) {
8281

8382
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "OSReceiveReceiptController enqueueing send receive receipt work with notificationId: " + osNotificationId + " and delay: " + delay + " seconds");
8483

85-
WorkManager.getInstance(context)
84+
OSWorkManagerHelper.getInstance(context)
8685
.enqueueUniqueWork(osNotificationId + "_receive_receipt", ExistingWorkPolicy.KEEP, workRequest);
8786
}
8887

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Modified MIT License
3+
* <p>
4+
* Copyright 2023 OneSignal
5+
* <p>
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
* <p>
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
* <p>
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
* <p>
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
package com.onesignal
29+
30+
import android.annotation.SuppressLint
31+
import android.content.Context
32+
import androidx.work.Configuration
33+
import androidx.work.WorkManager
34+
import androidx.work.impl.WorkManagerImpl
35+
36+
object OSWorkManagerHelper {
37+
/**
38+
* Helper method to provide a way to check if WorkManager is initialized in this process.
39+
*
40+
* This is effectively the `WorkManager.isInitialized()` public method introduced in androidx.work:work-*:2.8.0-alpha02.
41+
* Please see https://android-review.googlesource.com/c/platform/frameworks/support/+/1941186.
42+
*
43+
* @return `true` if WorkManager has been initialized in this process.
44+
*/
45+
@SuppressWarnings("deprecation")
46+
@SuppressLint("RestrictedApi")
47+
private fun isInitialized(): Boolean {
48+
val instance = WorkManagerImpl.getInstance()
49+
return instance != null
50+
}
51+
52+
/**
53+
* If there is an instance of WorkManager available, use it. Else, in rare cases, initialize it ourselves.
54+
*
55+
* Calling `WorkManager.getInstance(context)` directly can cause an exception if it is null.
56+
*
57+
* @return an instance of WorkManager
58+
*/
59+
@JvmStatic
60+
fun getInstance(context: Context): WorkManager {
61+
return if (isInitialized()) {
62+
WorkManager.getInstance(context)
63+
} else {
64+
WorkManager.initialize(context, Configuration.Builder().build())
65+
WorkManager.getInstance(context)
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)