首页 > 解决方案 > WorkManager 的 ForceStopRunnable 中的 SQLiteException

问题描述

我正在使用android.arch.work:work-runtime-ktx:1.0.1-rc1并收到许多无法重现的 SQLiteException。

例外:

android.database.sqlite.SQLiteException: 
  at android.database.sqlite.SQLiteConnection.nativeOpen (Native Method)
  at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:209)
  at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:193)
  at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked (SQLiteConnectionPool.java:463)
  at android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:185)
  at android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:177)
  at android.database.sqlite.SQLiteDatabase.openInner (SQLiteDatabase.java:808)
  at android.database.sqlite.SQLiteDatabase.open (SQLiteDatabase.java:793)
  at android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:696)
  at android.app.ContextImpl.openOrCreateDatabase (ContextImpl.java:652)
  at android.content.ContextWrapper.openOrCreateDatabase (ContextWrapper.java:289)
  at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:223)
  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:163)
  at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase (FrameworkSQLiteOpenHelper.java:92)
  at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase (FrameworkSQLiteOpenHelper.java:53)
  at androidx.room.RoomDatabase.endTransaction (RoomDatabase.java:340)
  at androidx.work.impl.utils.ForceStopRunnable.run (ForceStopRunnable.java:107)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
  at java.lang.Thread.run (Thread.java:761)

像这样安排工人:

inline fun <reified T : Worker> schedule(interval: Long,
                                             units: TimeUnit,
                                             tag: String,
                                             networkConstraint: NetworkType? = null) {
            WorkManager.getInstance().apply {
                if (getWorkInfosByTag(tag).get()
                                .all { it.state == WorkInfo.State.CANCELLED || it.state == WorkInfo.State.FAILED }) {
                    // Cancel job by tag if the job already scheduled
                    cancelAllWorkByTag(tag)

                    // Create job and set tag
                    val job = PeriodicWorkRequestBuilder<T>(interval, units).addTag(tag)

                    // Set constraint if networkConstraint != null
                    networkConstraint?.let {
                        val constraints = Constraints.Builder()
                                .setRequiredNetworkType(networkConstraint)
                                .build()

                        job.setConstraints(constraints)
                    }

                    // Enqueue periodic job if no previous job with same tag is scheduled.
                    enqueueUniquePeriodicWork(
                            tag,
                            ExistingPeriodicWorkPolicy.KEEP,
                            job.build())
                }
            }
    }

如果它很重要,则其中一个工作人员的调度会在其中执行一次,Application#onCreate()然后在用户交互之后再安排另一个工作人员。

工人本身是这样的:

internal class SiloWorker(context: Context, params: WorkerParameters)
    : Worker(context, params) {
    override fun doWork(): Result {
        if (isAppInBackground)
            return Result.success()

        doIntenseDatabaseAndNetworkIOOperations()

        return Result.success()
    }
}

并计划每 15 分钟运行一次。

另一个奇怪的事情是,我只在 Google Play Console 的“Android Vitals”选项卡上收到这些异常,但我在 Firebase crashlytics 中没有发现它们。

我不知道这些 SQLiteExceptions 是发生在前台还是后台,并且有许多具有不同 Android 版本的设备受此异常影响。

这种行为的可能原因是什么,我该如何解决?

标签: androidandroid-roomandroid-workmanager

解决方案


我们在2.1.0-alpha03. 试试看那个版本。


推荐阅读