WorkManager 尝试在 Application#onCreate 中排队独特的定期工作时崩溃

Lin*_*ton 6 android android-workmanager

我想将 WorkManager 与 Dagger 2 一起使用,将依赖项注入到工作人员中。我按照这篇文章来实现设置。设置部分是按需初始化。为了实现它,我将以下行添加到我的清单文件中:

\n\n
    <provider\n        android:name="androidx.work.impl.WorkManagerInitializer"\n        android:authorities="${applicationId}.workmanager-init"\n        android:exported="false"\n        tools:node="remove" />\n
Run Code Online (Sandbox Code Playgroud)\n\n

并使我的应用程序类实现Configuration.Provider如下接口:

\n\n
    @NonNull\n    @Override\n    public Configuration getWorkManagerConfiguration() {\n        return new Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).setWorkerFactory(delegatingWorkerFactory).build();\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

Dagger 设置按预期工作。

\n\n

但是我遇到了以下问题:在Application#onCreate我将唯一的定期任务排入队列并在第一次安装应用程序时,此操作总是失败并出现以下错误:

\n\n
java.lang.IllegalStateException: The file system on the device is in a bad state. WorkManager cannot access the app\'s internal data store.\n    at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:115)\n    at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)\n    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)\n    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)\n    at java.lang.Thread.run(Thread.java:764)\n Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14 SQLITE_CANTOPEN): Could not open database\n    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)\n    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:211)\n    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:195)\n    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:503)\n    at android.database.sqlite.SQLiteConnectionPool.tryAcquireNonPrimaryConnectionLocked(SQLiteConnectionPool.java:987)\n    at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:693)\n    at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:378)\n    at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894)\n    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:586)\n    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)\n    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)\n    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)\n    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408)\n    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1383)\n    at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.java:161)\n    at androidx.room.RoomDatabase.query(RoomDatabase.java:328)\n    at androidx.room.util.DBUtil.query(DBUtil.java:83)\n    at androidx.work.impl.model.PreferenceDao_Impl.getLongValue(PreferenceDao_Impl.java:70)\n    at androidx.work.impl.utils.PreferenceUtils.getNeedsReschedule(PreferenceUtils.java:96)\n    at androidx.work.impl.utils.ForceStopRunnable.shouldRescheduleWorkers(ForceStopRunnable.java:187)\n    at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:88)\n    at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)\xc2\xa0\n    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)\xc2\xa0\n    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)\xc2\xa0\n    at java.lang.Thread.run(Thread.java:764)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我将将工作排入队列的代码从Application#onCreate应用程序生命周期的后期(例如某些活动)移至队列,那么它就不会失败。

\n\n

我没有发现任何对排队工作的限制,Application#onCreate因此我希望它一定可以工作。\n我正在使用 WorkManager 2.3.4 和 Room 2.2.5。我尝试将 Room 降级到 2.2.2,并将 WorkManager 降级到几个较旧的稳定版本,但没有帮助。该问题可以在具有不同 Android 版本的不同设备和模拟器上重现。

\n\n

我该如何解决这个问题并继续排队工作Application#onCreate

\n\n

编辑\n这是我对工作进行排队的方式:

\n\n
workManagerProvider.get().enqueueUniquePeriodicWork(\n        "Unique name",\n        ExistingPeriodicWorkPolicy.REPLACE,\n        request\n    )\n
Run Code Online (Sandbox Code Playgroud)\n\n

哪里。workManagerProviderProvider<WorkManager>由于循环依赖,我无法直接访问工作管理器,因此我必须从 dagger 获取提供程序,然后才能使用它。这与主题无关。

\n

Lin*_*ton 1

该问题是由另一段代码引起的,该代码在首次启动时擦除应用程序的内部数据。WorkManager擦除与内部数据库创建有点并行。因此,在初始化期间WorkManager尝试访问已删除的数据库文件的 SQLite 连接,从而导致崩溃。

  • 好的,但是,你是怎么解决这个问题的? (2认同)