From bccbb9900ff01f67d353f47d4d060188d0d067ad Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:39:23 +0000 Subject: [PATCH] android: fix initializing WorkManager (#4833) --- .../chat/simplex/app/MessagesFetcherWorker.kt | 7 +++---- .../src/main/java/chat/simplex/app/SimplexApp.kt | 10 +++++++--- .../main/java/chat/simplex/app/SimplexService.kt | 2 +- .../simplex/common/platform/AppCommon.android.kt | 15 +++++++++++++++ .../views/usersettings/SettingsView.android.kt | 3 +-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt index 64b6639a58..b18204d905 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt @@ -5,9 +5,8 @@ import android.util.Log import androidx.work.* import chat.simplex.app.SimplexService.Companion.showPassphraseNotification import chat.simplex.common.model.ChatController +import chat.simplex.common.platform.* import chat.simplex.common.views.helpers.DBMigrationResult -import chat.simplex.common.platform.chatModel -import chat.simplex.common.platform.initChatControllerOnStart import chat.simplex.common.views.helpers.DatabaseUtils import kotlinx.coroutines.* import java.util.Date @@ -30,12 +29,12 @@ object MessagesFetcherWorker { .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()) .build() - WorkManager.getInstance(SimplexApp.context).enqueueUniqueWork(UNIQUE_WORK_TAG, ExistingWorkPolicy.REPLACE, periodicWorkRequest) + SimplexApp.context.getWorkManagerInstance().enqueueUniqueWork(UNIQUE_WORK_TAG, ExistingWorkPolicy.REPLACE, periodicWorkRequest) } fun cancelAll() { Log.d(TAG, "Worker: canceled all tasks") - WorkManager.getInstance(SimplexApp.context).cancelUniqueWork(UNIQUE_WORK_TAG) + SimplexApp.context.getWorkManagerInstance().cancelUniqueWork(UNIQUE_WORK_TAG) } } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt index 9206b5be89..d10f16341a 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt @@ -7,7 +7,6 @@ import chat.simplex.common.platform.Log import android.content.Intent import android.content.pm.ActivityInfo import android.os.* -import android.view.View import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.graphics.Color @@ -37,7 +36,7 @@ import java.util.concurrent.TimeUnit const val TAG = "SIMPLEX" -class SimplexApp: Application(), LifecycleEventObserver { +class SimplexApp: Application(), LifecycleEventObserver, Configuration.Provider { val chatModel: ChatModel get() = chatController.chatModel @@ -161,7 +160,7 @@ class SimplexApp: Application(), LifecycleEventObserver { .addTag(SimplexService.SERVICE_START_WORKER_WORK_NAME_PERIODIC) .build() Log.d(TAG, "ServiceStartWorker: Scheduling period work every ${SimplexService.SERVICE_START_WORKER_INTERVAL_MINUTES} minutes") - WorkManager.getInstance(context)?.enqueueUniquePeriodicWork(SimplexService.SERVICE_START_WORKER_WORK_NAME_PERIODIC, workPolicy, work) + getWorkManagerInstance().enqueueUniquePeriodicWork(SimplexService.SERVICE_START_WORKER_WORK_NAME_PERIODIC, workPolicy, work) } fun schedulePeriodicWakeUp() = CoroutineScope(Dispatchers.Default).launch { @@ -364,4 +363,9 @@ class SimplexApp: Application(), LifecycleEventObserver { } } } + + // Fix for an exception: + // WorkManager is not initialized properly. You have explicitly disabled WorkManagerInitializer in your manifest, have not manually called WorkManager#initialize at this point, and your Application does not implement Configuration.Provider. + override val workManagerConfiguration: Configuration + get() = Configuration.Builder().build() } diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt index a5f5d84ec2..7fc1bd151c 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt @@ -272,7 +272,7 @@ class SimplexService: Service() { fun scheduleStart(context: Context) { Log.d(TAG, "Enqueuing work to start subscriber service") - val workManager = WorkManager.getInstance(context) + val workManager = context.getWorkManagerInstance() val startServiceRequest = OneTimeWorkRequest.Builder(ServiceStartWorker::class.java).build() workManager.enqueueUniqueWork(WORK_NAME_ONCE, ExistingWorkPolicy.KEEP, startServiceRequest) // Unique avoids races! } diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt index d739a033f9..8cd51e8298 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt @@ -6,6 +6,8 @@ import android.net.LocalServerSocket import android.util.Log import androidx.activity.ComponentActivity import androidx.fragment.app.FragmentActivity +import androidx.work.Configuration +import androidx.work.WorkManager import java.io.* import java.lang.ref.WeakReference import java.util.* @@ -72,3 +74,16 @@ fun initHaskell() { initHS() } + +fun Context.getWorkManagerInstance(): WorkManager { + // https://github.com/OneSignal/OneSignal-Android-SDK/pull/2052/files + // https://github.com/OneSignal/OneSignal-Android-SDK/issues/1672 + if (!WorkManager.isInitialized()) { + try { + WorkManager.initialize(this, Configuration.Builder().build()) + } catch (e: IllegalStateException) { + Log.e(TAG, "Error initializing WorkManager: ${e.stackTraceToString()}") + } + } + return WorkManager.getInstance(this) +} diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt index 38818a123d..96b4a43e1a 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.android.kt @@ -2,7 +2,6 @@ package chat.simplex.common.views.usersettings import SectionView import androidx.compose.runtime.Composable -import androidx.work.WorkManager import chat.simplex.common.model.ChatModel import chat.simplex.common.platform.* import chat.simplex.common.views.helpers.* @@ -33,7 +32,7 @@ fun restartApp() { } private fun shutdownApp() { - WorkManager.getInstance(androidAppContext).cancelAllWork() + androidAppContext.getWorkManagerInstance().cancelAllWork() platform.androidServiceSafeStop() Runtime.getRuntime().exit(0) }