Status Update
Comments
na...@onesignal.com <na...@onesignal.com> #3
Hi,
To clarify, does this resolve the issue for an application that uses the default WorkManager
initializer (doesn't initialize WorkManager itself), and not using multiprocess
/android:process
at all?
That's the type of application that we see encountering this crash.
I see in source code for RemoteWorkManager.java
and RemoteWorkManagerWorkManagerImpl.java
that they call WorkManagerImpl.getInstance(context)
, and this method is what triggers the crash reports. I'm not sure that using RemoteWorkManager
will resolve this for us.
mr...@gmail.com <mr...@gmail.com> #4
But I can see these issues at least 10 months, what should we do?
mu...@gmail.com <mu...@gmail.com> #5
en...@gmail.com <en...@gmail.com> #6
Do you have any updates?
Original crash still reproduces on store builds
ra...@google.com <ra...@google.com> #7
My guess is another app component is trying to use OneSignal
/ WorkManager
before its actually initialized.
This can easily happen. OneSignal
should not rely on androidx.startup
given developers might want to use OneSignal's SDK before WorkManager
was initialized in the app process.
This ends up looking like an issue in the library, but its really a bug in the app given the developer cannot reason about what to initialize first.
OneSignal
should check to see if WorkManager
was initialized by using WorkManager.initialize(context, Configuration.Builder().build())
.
na...@onesignal.com <na...@onesignal.com> #8
Thank you for the response,
I believe you are correct if OneSignal
is initialized in a Content Provider, but it is not. It is initialized in app developers' Application.onCreate
.
The default Work Manger should be initialized by androidx.startup
, which should be initialized before the Application
class, right?
We can still try the speculative fix to initialize Work Manager ourselves if it is null
, but because we don’t completely understand this crash, it will be speculative and we are concerned that the app can run into a different crash (the one that says WorkManager is already initialized
when the default initializer goes to create it).
However, maybe it doesn't run into that second crash and this crash would be fixed. We just don't understand how this crash happens.
ha...@gmail.com <ha...@gmail.com> #9
ya...@moloco.com <ya...@moloco.com> #10
ve...@lasergame.de <ve...@lasergame.de> #11
na...@onesignal.com <na...@onesignal.com> #12
I am the original reporter. We made a speculative fix to initialize WorkManager ourselves when we run into this exception. However, we have not been able to fully resolve it from just our end. Some users of the OneSignal SDK then encountered issues with Hilt dependency manager, and others reported this new exception:
IllegalStateException: WorkManager is already initialized. Did you try to initialize it manually without disabling WorkManagerInitializer? See WorkManager#initialize(Context, Configuration) or the class level Javadoc for more information.
se...@google.com <se...@google.com> #13
IllegalStateException: WorkManager is already initialized. Did you try to initialize it manually without disabling WorkManagerInitializer? See WorkManager#initialize(Context, Configuration) or the class level Javadoc for more information.
This errors points to the race condition between different codepaths that try to initialise workManager. One way to resolve it on your end could be is add WorkManager as the explicit parameter to your SDK (e.g. MySdkBuilder().setWorkManager(...)
). This way your SDK is never responsible for initialisation of WorkManager and won't run into the issues related to it.
Overall it goes into the bucket of "Library Mode" for workmanager, where we would have special patterns for library developers who depend on WorkManager.
na...@onesignal.com <na...@onesignal.com> #14
This errors points to the race condition between different codepaths that try to initialise workManager. One way to resolve it on your end could be is add WorkManager as the explicit parameter to your SDK (e.g. MySdkBuilder().setWorkManager(...)). This way your SDK is never responsible for initialisation of WorkManager and won't run into the issues related to it.
We added a synchronized try-catch
around accessing the default WorkManager so that if we encounter the rare exception:
"WorkManager is not initialized properly. You have explicitly disabled WorkManagerInitializer...."
, the SDK initializes it ourselves, but this was simply an attempted fix at the root issue.
The root issue is that no one is managing WorkManager, initializing WorkManager, or overriding the default initializer. The SDK consumers are not using WorkManager in their code, and our SDK was just using the default one by calling WorkManager.getInstance(context)
.
Overall it goes into the bucket of "Library Mode" for workmanager, where we would have special patterns for library developers who depend on WorkManager.
How should our library be using WorkManager if we don't want to manage it, or initialize it, and just want to use the default WorkManager, and our clients are not using WorkManager? Since that is what we were trying to do in the first place.
Thank you for your help
mo...@onsurity.com <mo...@onsurity.com> #15
I used the @BeforeClass annotation with JUnit 4. Annotating a method with @BeforeClass ensured that the function was executed only once before any test cases in the class were run. This helped prevent the work manager from initialising multiple times during my tests.
here is the source code:
companion object {
@JvmStatic
@BeforeClass
fun initializeWorkManager() {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
val config = Configuration.Builder().setMinimumLoggingLevel(Log.INFO).build()
WorkManager.initialize(appContext, config)
}
}
Description
Component used:
androidx.work:work-runtime
Version used: Many versions in the range
2.1 - 2.7.1
Devices/Android versions reproduced on:
6 - 12
Description
I am from the OneSignal SDK team and we use
WorkManager
in our mobile SDKs. We have seen many reported crashes from end users for this particular WorkManager IllegalStateException:However, the OneSignal SDK uses the default
WorkManagerInitializer
and does not disable it. We were able to investigate several end users' merged Android Manifests and app information, and find this crash happens for users who are not using multiple processes, not using WorkManager themselves, and not disabling the default initializer.This crash is reported by users on a range of work-runtime versions from
2.1
through2.7.1
. It also appears to affect devices across types, brands, and Android versions.Our native SDK users could work around this by implementing a custom WorkManagerInitializer for their app by following the On-Demand Initialization guide, but this is not a solution for non-native app developers such as those using Flutter and Unity, for example. Given this, it's important for a root fix from the library itself.
We speculate it may have to do with the initialization of libraries and components during an app's startup process, and encountering edge cases where OneSignal tries to access the
WorkManager
singleton but it has not yet been initialized by the system.If there are many providers to initialize, the one that contains the
WorkManagerInitializer
may not get created until later in the process, making this more likely.Does this sound like a correct interpretation of the issue?
What recommendations do you have for how to work around or resolve this from our end?
We considered checking for WorkManager's existence before accessing it, and initializing it ourselves, but I believe that we will encounter the "WorkManager is already initialized" exception shortly after, when the default initializer tries to initialize it as well.
We have also posted a public issue on our native Android SDK's GitHub to collect information from app developers that may have relevant information for this issue.
Sources of this crash
From reported stacktraces, these are the 3 places in our codebase that we call
WorkManager.getInstance(context)
that creates this exception:Selection of stacktraces