android - 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 版本的设备受此异常影响。
这种行为的可能原因是什么,我该如何解决?
解决方案
我们在2.1.0-alpha03
. 试试看那个版本。
推荐阅读
- javascript - 是否可以将 Web 扩展与 MIME 类型相关联?
- pdf - Microsoft 信息保护(MIP)统一标签,敏感标签可以作为页脚添加到 PDF 中吗?
- node.js - 带有子文档的 Array.map 表
- ios - 如何在 Swift 中调用功能键(F1、F2、F3)?
- python - 未能在 Django-Forms 中使用外键并出现错误
- c++ - 如何在 C++ 中使用 lame (mp3->wav) 进行解码
- c - 了解 time_t 调用
- java - 如何在堆栈中找到一个值并使用递归将其放在顶部?
- selenium - 我可以使用 selenium 在网站上单击此元素吗?
- javascript - Greasemonkey - 使用来自其他用户脚本的一个用户脚本(作为 js 库)