You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:25:06