Android 15 Pixel 9设备重启后Room数据库丢失(仅预填充时出现)
Android 15(Pixel 9)Room预填充数据库重启后数据丢失问题
问题场景
在Android 15(Pixel 9)设备上,使用Room的createFromAsset方法预填充数据库时,应用重启后所有存储数据丢失;不使用预填充逻辑时,数据持久化正常。
关联代码
@Provides @Singleton fun provideDatabase(@ApplicationContext context: Context): AppDatabase { return Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "app_database" ).createFromAsset("database/external_database.db") .enableMultiInstanceInvalidation() .fallbackToDestructiveMigration() .build() }
排查与解决方案
1. 版本不匹配触发破坏性迁移
- 检查
AppDatabase中@Database注解的version值,必须和资产里external_database.db的实际版本完全一致。 - 若资产数据库版本低于实体类定义的版本,
fallbackToDestructiveMigration()会直接销毁现有数据库并重建,导致数据丢失。建议替换为fallbackToDestructiveMigrationFrom(),仅指定需要破坏性迁移的旧版本:.fallbackToDestructiveMigrationFrom(1) // 仅当从版本1迁移失败时执行销毁重建
2. Android 15存储沙盒限制
Android 15收紧了应用私有存储的访问规则,可能导致Room无法正确保留修改后的数据库文件:
- 确认资产文件打包路径正确(
assets/database/external_database.db),避免路径错误导致重复复制初始数据库。 - 验证应用私有目录下的数据库文件(
/data/data/[你的包名]/databases/)在重启后是否被替换,可通过adb shell查看文件修改时间。
3. createFromAsset的默认覆盖逻辑
Room默认仅在数据库不存在时复制资产文件,但如果数据库文件损坏或版本校验失败,会触发重新复制,覆盖已有数据:
- 添加数据库回调,控制预填充仅在首次创建时执行:
.createFromAsset("database/external_database.db") .addCallback(object : RoomDatabase.Callback() { override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) // 仅首次创建数据库时执行预填充,后续重启不触发 } })
4. 多实例无效化的冲突
enableMultiInstanceInvalidation()用于多进程场景,单进程应用使用可能引发连接异常,间接导致数据丢失:
- 若你的应用是单进程架构,移除
enableMultiInstanceInvalidation()后测试。
验证步骤
- 过滤Room相关日志,查看是否有
DestructiveMigration或数据库重建的日志信息。 - 测试移除
createFromAsset后手动插入数据,重启应用确认数据是否正常持久化,排除Room基础配置问题。
内容的提问来源于stack exchange,提问作者Santhosh Kumar
相关产品推荐
相关产品推荐

