尝试在Application#onCreate中加入唯一的定期工作而导致WorkManager崩溃 [英] WorkManager crashes trying to enqueue unique periodic work in Application#onCreate

查看:385
本文介绍了尝试在Application#onCreate中加入唯一的定期工作而导致WorkManager崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将WorkManager与Dagger 2一起使用,以将依赖项注入到工作程序中.我关注了这篇文章实施设置.设置的一部分是按需初始化.为此,我在清单文件中添加了以下几行:

I want to use WorkManager together with Dagger 2 to inject dependencies into workers. I followed this article to implement the setup. The part of the setup is on-demand initialization. To achieve it I added the following lines into my manifest file:

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

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

and made my application class implement the Configuration.Provider interface like this:

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

匕首设置按预期工作.

但是,我遇到以下问题:在 Application#onCreate 中,我加入了唯一的定期任务,并且在首次安装该应用程序时,此操作始终失败,并出现以下错误:

However I encountered the following problem: in Application#onCreate I enqueue unique periodic task and on the very first installation of the application this action always fails with the following error:

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 移至应用程序生命周期的后期阶段(例如某些活动),那么它不会失败.

If I move the code that enqueue my work out from the Application#onCreate into later stage of the application lifecycle (some activity for example) then it doesn't fail.

我没有发现从 Application#onCreate 入队工作的任何限制,因此我希望它必须能够工作.我正在使用WorkManager 2.3.4和Room 2.2.5.我还尝试将Room降级为2.2.2,并将WorkManager降级为几个较旧的稳定版本,但这并没有帮助.在具有不同Android版本的不同设备和仿真器上都可以重现该问题.

I haven't found any restrictions on enqueuing work from Application#onCreate so I expect it must work. I'm using WorkManager 2.3.4 and Room 2.2.5. I tried to downgrade Room to 2.2.2 and WorkManager down to several older stable versions as well, but it didn't help. Issue is reproducible on different devices and emulators with different Android versions.

如何解决此问题并继续在 Application#onCreate 中排队工作?

How can I address this issue and keep enqueuing work in Application#onCreate?

编辑这是我对工作的征服方式:

EDIT Here's how I enquee the work:

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

其中 workManagerProvider Provider< WorkManager> .由于循环依赖,我无法直接访问工作管理器,因此我不得不从dagger获取提供程序,然后才可以使用它.与主题无关.

where workManagerProvider is Provider<WorkManager>. I can't access the workmanager directly due to circular dependency, so I had to get a provider from dagger and only then use it. It is not related to the topic.

推荐答案

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

The issue was caused by another piece of code, which was wiping application's internal data on the first launch. Wipe was performed kinda in parallel with the WorkManager's internal database creation. Because of that, during initialization WorkManager tried to access the SQLite connection for the already deleted database file and that led to the crash.

这篇关于尝试在Application#onCreate中加入唯一的定期工作而导致WorkManager崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆