【问题标题】:WorkManager crashes trying to enqueue unique periodic work in Application#onCreate [closed]WorkManager 崩溃,试图将 Application#onCreate 中的唯一周期性工作排入队列 [关闭]
【发布时间】:2020-05-20 10:07:17
【问题描述】:

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

    <provider
        android:name="androidx.work.impl.WorkManagerInitializer"
        android:authorities="${applicationId}.workmanager-init"
        android:exported="false"
        tools:node="remove" />

并让我的应用程序类实现Configuration.Provider 接口,如下所示:

    @NonNull
    @Override
    public Configuration getWorkManagerConfiguration() {
        return new Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).setWorkerFactory(delegatingWorkerFactory).build();
    }

Dagger 设置按预期工作。

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

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

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

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

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

编辑 以下是我入队的方式:

workManagerProvider.get().enqueueUniquePeriodicWork(
        "Unique name",
        ExistingPeriodicWorkPolicy.REPLACE,
        request
    )

其中workManagerProviderProvider&lt;WorkManager&gt;。由于循环依赖,我无法直接访问 workmanager,所以我必须从 dagger 获取提供程序,然后才能使用它。与主题无关。

【问题讨论】:

  • 从错误中可以理解是因为数据库无法打开。我认为在您将工作排入Application#onCreate 之前,数据库没有初始化
  • @Antonio 没错,但它是由 WorkManager 管理的数据库。所以我不知道是什么阻止了 WorkManager 在第一次运行时专门初始化它。
  • 您能否添加显示您如何将工作排入队列的代码?
  • Dagger2 和 WorkManager 正在您的代码中使用,并且两者都有自己的初始化步骤的方式,所以最好分享完整的示例代码,您如何尝试实现它,否则尝试“enqueueUniquePeriodicWork”而不在这里使用 Dagger2 看看这是否适合你。

标签: android android-workmanager


【解决方案1】:

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

【讨论】:

  • 好的,但是你是怎么解决这个问题的?
猜你喜欢
  • 2022-07-03
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多