从androidx.work.Worker将数据保存到文件室失败
我曾尝试将数据从员工数据库保存到房间数据库 版本:从androidx.work.Worker将数据保存到文件室失败,android,kotlin,android-room,android-workmanager,Android,Kotlin,Android Room,Android Workmanager,我曾尝试将数据从员工数据库保存到房间数据库 版本: Work-Runtime-Ktx-android.arch.Work:Work-Runtime-Ktx:1.0.0-alpha02 Room-android.arch.persistence.Room:runtime:1.1.0和 android.arch.persistence.room:compiler:1.1.0 MainActivity.kt private fun runDataDownloadWork() { W
- Work-Runtime-Ktx-android.arch.Work:Work-Runtime-Ktx:1.0.0-alpha02
- Room-android.arch.persistence.Room:runtime:1.1.0和 android.arch.persistence.room:compiler:1.1.0
private fun runDataDownloadWork() {
WorkManager.getInstance()
.beginWith(dwElementTypesWork)
.then(dwElementsWork)
.enqueue()
WorkManager.getInstance().getStatusById(dwElementsWork!!.id)
.observe(this, Observer { workStatus ->
if (workStatus != null && workStatus.state.isFinished) {
Log.d("WorkManager", "dwElementsWork finished")
}
})
}
private fun createWorkRequests() {
dwElementsWork = OneTimeWorkRequestBuilder<DWElementsWork>()
.addTag(DWElementsWork.TAG)
.setConstraints(wifiConstraints)
.build()
dwElementTypesWork = OneTimeWorkRequestBuilder<DWElementTypesWork>()
.addTag(DWElementTypesWork.TAG)
.setConstraints(wifiConstraints)
.build()
}
class DWElementsWork : Worker() {
companion object {
const val TAG = "dw_elements_work"
}
override fun doWork(): WorkerResult {
val apiService: APIService = ServiceGenerator
.createService(applicationContext, MyAPIService::class.java)
var elementDao: ElementDao? = AppDatabase
.getInstance(context = applicationContext)
.elementDao()
val response = apiService.getElements().execute()
if (response.isSuccessful) {
val elements = response.body()
try {
elementDao?.insertElements(elements!!)
} catch (e: Exception) {
e.printStackTrace()
} finally {
return WorkerResult.SUCCESS
}
}
Log.e("BACKGROUND_WORKER", response.errorBody()?.string())
return WorkerResult.FAILURE
}
}
@Database(entities = [
(Element::class)
], version = 9, exportSchema = false)
abstract class AppDatabase: RoomDatabase() {
abstract fun elementDao(): ElementDao
companion object {
private var sInstance: AppDatabase? = null
/**
* Gets the singleton instance of AppDatabase.
*
* @param context The context.
* @return The singleton instance of AppDatabase.
*/
@Synchronized
fun getInstance(context: Context): AppDatabase {
if (sInstance == null) {
sInstance = Room
.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"my_database.db"
)
.fallbackToDestructiveMigration()
.build()
}
return sInstance!!
}
}
}
AppDatabase.kt
private fun runDataDownloadWork() {
WorkManager.getInstance()
.beginWith(dwElementTypesWork)
.then(dwElementsWork)
.enqueue()
WorkManager.getInstance().getStatusById(dwElementsWork!!.id)
.observe(this, Observer { workStatus ->
if (workStatus != null && workStatus.state.isFinished) {
Log.d("WorkManager", "dwElementsWork finished")
}
})
}
private fun createWorkRequests() {
dwElementsWork = OneTimeWorkRequestBuilder<DWElementsWork>()
.addTag(DWElementsWork.TAG)
.setConstraints(wifiConstraints)
.build()
dwElementTypesWork = OneTimeWorkRequestBuilder<DWElementTypesWork>()
.addTag(DWElementTypesWork.TAG)
.setConstraints(wifiConstraints)
.build()
}
class DWElementsWork : Worker() {
companion object {
const val TAG = "dw_elements_work"
}
override fun doWork(): WorkerResult {
val apiService: APIService = ServiceGenerator
.createService(applicationContext, MyAPIService::class.java)
var elementDao: ElementDao? = AppDatabase
.getInstance(context = applicationContext)
.elementDao()
val response = apiService.getElements().execute()
if (response.isSuccessful) {
val elements = response.body()
try {
elementDao?.insertElements(elements!!)
} catch (e: Exception) {
e.printStackTrace()
} finally {
return WorkerResult.SUCCESS
}
}
Log.e("BACKGROUND_WORKER", response.errorBody()?.string())
return WorkerResult.FAILURE
}
}
@Database(entities = [
(Element::class)
], version = 9, exportSchema = false)
abstract class AppDatabase: RoomDatabase() {
abstract fun elementDao(): ElementDao
companion object {
private var sInstance: AppDatabase? = null
/**
* Gets the singleton instance of AppDatabase.
*
* @param context The context.
* @return The singleton instance of AppDatabase.
*/
@Synchronized
fun getInstance(context: Context): AppDatabase {
if (sInstance == null) {
sInstance = Room
.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"my_database.db"
)
.fallbackToDestructiveMigration()
.build()
}
return sInstance!!
}
}
}
当试图调用elementDao?时,主要问题就出现了。insertElements(elements!!)
它给出了以下错误:
StackTrace
06-20 15:57:09.660 25193-25226/com.myapp.app E/ROOM: Cannot run invalidation tracker. Is the db closed?
java.lang.IllegalStateException: The database '/data/user/0/com.myapp.app/databases/my_database.db' is not open.
at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2287)
at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:409)
at android.database.sqlite.-$$Lambda$RBWjWVyGrOTsQrLCYzJ_G8Uk25Q.get(Unknown Source:2)
at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284)
at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180)
at java.lang.ThreadLocal.get(ThreadLocal.java:170)
at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:403)
at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321)
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)
我在插入元素之前就停止了调试器,并且AppDatabase.getInstance(applicationContext).isOpen
返回false
我做错什么了吗
是否可以将工人的数据保存到房间
可能applicationContext(getApplicationContext())没有提供正确的上下文和应用数据库,因为它的实例化很糟糕
提前谢谢 您是否尝试过使用最新版本的Room and WorkManager?它们目前分别为1.1.1和1.1.0-alpha3。(只是为了确保它不是最新版本中修复的已知错误)您是否尝试过从空状态执行此操作?如果迁移失败,则会引发此类异常。应用程序在某个时间点开始正常工作,@MatPag在这之后更新了两个库。没有做任何不同的事情,可能是一个干净的安装,正如ImidGod所说。@ImidGod从emtpy状态启动它似乎可以解决这个问题,但我已经回退到DestructiveMigration选项处于活动状态,因为我没有创建任何迁移方案,它应该删除数据库并从零开始重新创建它。我不知道为什么在某个时候它不起作用。我投票结束这个问题,因为它已经过时了,图书馆工程师的官方答案已经被版主删除了。