Room数据库在APP关闭重启后重置,收藏数据丢失求助
问题根源及解决办法
核心问题
你遇到的数据丢失是因为Room数据库每次启动时都会销毁现有库并从assets重新初始化,触发这个行为的关键原因有两个:
assets中的初始数据库与代码定义的实体不匹配
你代码里定义了Airport和Favorite两个实体,但assets里的flight_search.db很可能没有Favorite表,或者表结构和Favorite实体不一致。Room检测到这种结构不匹配时,会认为需要数据库迁移。fallbackToDestructiveMigration()的破坏性作用
你在数据库构建时添加了这个方法,它的作用是:当Room无法完成数据库迁移时,直接删除现有数据库并重新创建。结合上面的结构不匹配问题,每次APP重启都会触发这个逻辑,导致用户新增的收藏数据被清空,回到初始状态。
具体解决步骤
步骤1:修复assets数据库的结构和版本
用SQLite浏览器打开assets/database/flight_search.db,做以下检查和修改:
- 确认存在
Favorite表,且表字段、类型、约束和你代码中的Favorite实体完全一致。 - 查看
room_master_table中的version值,确保和代码中@Database(version = 1)的版本号一致。
步骤2:修改数据库构建逻辑
移除fallbackToDestructiveMigration()方法,避免触发破坏性销毁:
fun getDatabase(context: Context): FlightsDatabase { return Instance ?: synchronized(this) { Room.databaseBuilder( context, FlightsDatabase::class.java, "app_database" ) .createFromAsset("database/flight_search.db") // 移除fallbackToDestructiveMigration,后续如需升级数据库,可添加自定义迁移规则 .build() .also { Instance = it } } }
步骤3:优化DAO中的查询逻辑
你的getFavoriteByIATAS返回Flow<Favorite>?,但在仓库的insertFavorite方法中是做单次查询,不需要监听数据变化,改成suspend的单次查询更合适:
// DAO中修改 @Query("SELECT * FROM favorite WHERE departure_code = :departureCode AND destination_code = :destinationCode") suspend fun getFavoriteByIATAS(departureCode: String, destinationCode: String): Favorite? // 仓库中修改 override suspend fun insertFavorite(favorite: Favorite) { val foundFavorite = flightsDao.getFavoriteByIATAS(favorite.departureCode, favorite.destinationCode) if (foundFavorite != null) { flightsDao.deleteFavorite(foundFavorite) } else { flightsDao.insertFavorite(favorite) } }
额外验证
修改完成后,卸载现有APP重新安装,测试添加收藏后重启APP,确认数据是否保留。
内容的提问来源于stack exchange,提问作者NullPointerException
相关产品推荐
相关产品推荐

