|
27 | 27 |
|
28 | 28 | package com.onesignal
|
29 | 29 |
|
30 |
| -import android.annotation.SuppressLint |
31 | 30 | import android.content.Context
|
32 | 31 | import androidx.work.Configuration
|
33 | 32 | import androidx.work.WorkManager
|
34 |
| -import androidx.work.impl.WorkManagerImpl |
35 | 33 |
|
36 | 34 | 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 |
| - return WorkManagerImpl.getInstance() != null |
49 |
| - } |
50 |
| - |
51 | 35 | /**
|
52 | 36 | * If there is an instance of WorkManager available, use it. Else, in rare cases, initialize it ourselves.
|
53 | 37 | *
|
54 | 38 | * Calling `WorkManager.getInstance(context)` directly can cause an exception if it is null.
|
| 39 | + * However, this is the appropriate way to check as the non-throwing `WorkManager.getInstance()` |
| 40 | + * method does not allow the opportunity for on-demand initialization with custom WorkManager. |
| 41 | + * |
| 42 | + * The purpose of this helper is to work around this bug - https://issuetracker.google.com/issues/258176803 |
55 | 43 | *
|
56 | 44 | * @return an instance of WorkManager
|
57 | 45 | */
|
58 | 46 | @JvmStatic
|
59 | 47 | @Synchronized
|
60 | 48 | fun getInstance(context: Context): WorkManager {
|
61 |
| - if (!isInitialized()) { |
62 |
| - WorkManager.initialize(context, Configuration.Builder().build()) |
| 49 | + return try { |
| 50 | + WorkManager.getInstance(context) |
| 51 | + } catch (e: IllegalStateException) { |
| 52 | + /* |
| 53 | + This aims to catch the IllegalStateException "WorkManager is not initialized properly..." - |
| 54 | + https://androidx.tech/artifacts/work/work-runtime/2.8.1-source/androidx/work/impl/WorkManagerImpl.java.html |
| 55 | + */ |
| 56 | + OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "OSWorkManagerHelper.getInstance failed, attempting to initialize: ", e) |
| 57 | + initializeWorkManager(context) |
| 58 | + WorkManager.getInstance(context) |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + /** |
| 63 | + * This method is called in rare cases to initialize WorkManager ourselves. |
| 64 | + */ |
| 65 | + private fun initializeWorkManager(context: Context) { |
| 66 | + try { |
| 67 | + /* |
| 68 | + Note: `WorkManager.getInstance(context)` should already initialize WorkManager when the |
| 69 | + application implements Configuration.Provider. However, as a further safeguard, let's detect |
| 70 | + for this when we attempt to initialize WorkManager. |
| 71 | + */ |
| 72 | + val configuration = (context.applicationContext as? Configuration.Provider)?.workManagerConfiguration ?: Configuration.Builder().build() |
| 73 | + WorkManager.initialize(context, configuration) |
| 74 | + } catch (e: IllegalStateException) { |
| 75 | + /* |
| 76 | + This catch is meant for the exception - |
| 77 | + https://android.googlesource.com/platform/frameworks/support/+/60ae0eec2a32396c22ad92502cde952c80d514a0/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java#177 |
| 78 | + 1. We lost the race with another call to WorkManager.initialize outside of OneSignal. |
| 79 | + 2. It is possible for some other unexpected error is thrown from WorkManager. |
| 80 | + */ |
| 81 | + OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "OSWorkManagerHelper initializing WorkManager failed: ", e) |
63 | 82 | }
|
64 |
| - return WorkManager.getInstance(context) |
65 | 83 | }
|
66 | 84 | }
|
0 commit comments