Skip to content

Commit

Permalink
fix crash with WorkManager helper for initialization
Browse files Browse the repository at this point in the history
* 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

* Please see issue this aims to address: #1672
  • Loading branch information
nan-li committed Jan 19, 2023
1 parent a9e796e commit a16ae65
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import androidx.work.Constraints
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -87,7 +86,8 @@ class OSFocusHandler {
.setInitialDelay(delay, TimeUnit.MILLISECONDS)
.addTag(tag)
.build()
WorkManager.getInstance(context)

OSWorkManagerHelper.getInstance(context)
.enqueueUniqueWork(
tag,
ExistingWorkPolicy.KEEP,
Expand All @@ -96,7 +96,7 @@ class OSFocusHandler {
}

fun cancelOnLostFocusWorker(tag: String, context: Context) {
WorkManager.getInstance(context).cancelAllWorkByTag(tag)
OSWorkManagerHelper.getInstance(context).cancelAllWorkByTag(tag)
}

private fun resetStopState() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import androidx.annotation.NonNull;
import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

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

WorkManager.getInstance(context)
OSWorkManagerHelper.getInstance(context)
.enqueueUniqueWork(NOTIFICATION_RESTORE_WORKER_IDENTIFIER, ExistingWorkPolicy.KEEP, workRequest);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import androidx.work.Data;
import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

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

OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "OSNotificationWorkManager enqueueing notification work with notificationId: " + osNotificationId + " and jsonPayload: " + jsonPayload);
WorkManager.getInstance(context)
.enqueueUniqueWork(osNotificationId, ExistingWorkPolicy.KEEP, workRequest);

OSWorkManagerHelper.getInstance(context).
enqueueUniqueWork(osNotificationId, ExistingWorkPolicy.KEEP, workRequest);
}

public static class NotificationWorker extends Worker {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import androidx.work.ExistingWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

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

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

WorkManager.getInstance(context)
OSWorkManagerHelper.getInstance(context)
.enqueueUniqueWork(osNotificationId + "_receive_receipt", ExistingWorkPolicy.KEEP, workRequest);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Modified MIT License
* <p>
* Copyright 2023 OneSignal
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* 1. The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* 2. All copies of substantial portions of the Software may only be used in connection
* with services provided by OneSignal.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.onesignal

import android.annotation.SuppressLint
import android.content.Context
import androidx.work.Configuration
import androidx.work.WorkManager
import androidx.work.impl.WorkManagerImpl

object OSWorkManagerHelper {
/**
* Helper method to provide a way 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.
*
* @return `true` if WorkManager has been initialized in this process.
*/
@SuppressWarnings("deprecation")
@SuppressLint("RestrictedApi")
private fun isInitialized(): Boolean {
val instance = WorkManagerImpl.getInstance()
return instance != null
}

/**
* If there is an instance of WorkManager available, use it. Else, in rare cases, initialize it ourselves.
*
* Calling `WorkManager.getInstance(context)` directly can cause an exception if it is null.
*
* @return an instance of WorkManager
*/
@JvmStatic
fun getInstance(context: Context): WorkManager {
return if (isInitialized()) {
WorkManager.getInstance(context)
} else {
WorkManager.initialize(context, Configuration.Builder().build())
WorkManager.getInstance(context)
}
}
}

0 comments on commit a16ae65

Please sign in to comment.