Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从androidx.work.Worker将数据保存到文件室失败_Android_Kotlin_Android Room_Android Workmanager - Fatal编程技术网

从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
MainActivity.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!!
        }
    }
}
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选项处于活动状态,因为我没有创建任何迁移方案,它应该删除数据库并从零开始重新创建它。我不知道为什么在某个时候它不起作用。我投票结束这个问题,因为它已经过时了,图书馆工程师的官方答案已经被版主删除了。