在某些 api 级别使用 Room 时出现空 SQLiteException

问题描述 投票:0回答:1

加载我的应用程序时遇到此错误:

2024-10-29 13:29:19.532  3647-3854  SQLiteLog               org.druidanet.druidnet               E  (1) 
2024-10-29 13:29:19.727  3647-3647  AndroidRuntime          org.druidanet.druidnet               E  FATAL EXCEPTION: main
                                                                                                    Process: org.druidanet.druidnet, PID: 3647
                                                                                                    android.database.sqlite.SQLiteException: no such column: TRUE (Sqlite code 1): , while compiling: SELECT common_name, plantId, image_path, latin_name,language FROM PlantView ORDER BY common_name, (OS error - 88:Socket operation on non-socket)
                                                                                                        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                                                        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:925)
                                                                                                        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:536)
                                                                                                        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:603)
                                                                                                        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:63)
                                                                                                        at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                                                        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                                                        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1397)
                                                                                                        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1367)
                                                                                                        at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.kt:156)
                                                                                                        at androidx.room.RoomDatabase.query(RoomDatabase.kt:484)
                                                                                                        at androidx.room.util.DBUtil.query(DBUtil.kt:75)
                                                                                                        at org.druidanet.druidnet.data.PlantDAO_Impl$1.call(PlantDAO_Impl.java:47)
                                                                                                        at org.druidanet.druidnet.data.PlantDAO_Impl$1.call(PlantDAO_Impl.java:43)
                                                                                                        at androidx.room.CoroutinesRoom$Companion$createFlow$1$1$1.invokeSuspend(CoroutinesRoom.kt:129)
                                                                                                        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                                                                        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
                                                                                                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
                                                                                                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
                                                                                                        at java.lang.Thread.run(Thread.java:784)

我尝试使用带有 Oreo(API 级别 26)的物理平板电脑和具有相同 API 级别的虚拟机,但出现了崩溃。但是,在许多其他设备中,例如 Android 11(API 级别 30),它可以无缝运行。

我使用 Room 创建了数据库并使用资产对其进行初始化:

@Database(entities = [PlantEntity::class, UsageEntity::class, NameEntity::class, ConfusionEntity::class],
          views =[PlantView::class],
          version = 1)
abstract class AppDatabase: RoomDatabase() {

    abstract fun plantDao(): PlantDAO

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null


        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                Room.databaseBuilder(
                    context,
                    AppDatabase::class.java,
                    "druid_database"
                )
                    // Wipes and rebuilds instead of migrating if no Migration object.
                    .fallbackToDestructiveMigration()
                    .createFromAsset("databases/druid_database.db")
                    .build()
                    .also {
                        INSTANCE = it
                    }
            }
        }
    }
}
android sqlite android-room android-api-levels
1个回答
0
投票

我刚刚发现了这个错误!

旧版本的 SQLite(API 级别 30 之前)不支持 TRUE / FALSE 作为 1 / 0 的同义词。

创建 SQL 视图来执行查询时,我使用关键字 TRUE 而不是 1:

@DatabaseView("SELECT p.plantId, p.latin_name, n.common_name, n.language, p.image_path" +
        " FROM Plant p JOIN Name n ON p.plantId = n.plantId WHERE isDisplayName = TRUE"
)

它适用于现代版本的 SQLite,但不适用于旧版本。

用 1 替换 TRUE 就可以了!

PD:感谢 ChatGPT,它帮助我找到了错误!

© www.soinside.com 2019 - 2024. All rights reserved.