Android Room迁移疑问:全新安装时如何执行全版本迁移?
实现Room全新安装时执行全量迁移的方案
完全可行!Room默认的行为确实是全新安装时直接根据当前@Entity创建最新版本的数据库,跳过所有迁移——这是为了避免不必要的性能开销,但你的场景需要统一迁移逻辑,不管是升级还是全新安装都走相同的流程,下面是具体的实现方法:
核心思路
Room只有在已存在的数据库版本低于当前版本时才会触发迁移。要让全新安装也执行1→2→3→4的迁移,我们需要先让Room创建/加载一个v1版本的初始数据库,再让它自动执行后续的迁移步骤。
具体步骤
1. 准备v1版本的初始数据库
首先,确保你已经有v1版本的Schema文件(Room会在build/generated/schemas/[你的包名]/[数据库名]/1.json生成)。你需要基于这个Schema创建一个空的v1数据库文件(或者包含v1种子数据的数据库):
- 可以用SQLite工具(比如DB Browser for SQLite)手动创建,对应v1的表结构;
- 也可以先跑一次仅包含v1实体类的App,导出生成的数据库文件。
把这个v1数据库文件放到你的Android项目的assets/databases/目录下(如果没有就创建对应的文件夹),比如命名为my_app_db_v1.db。
2. 配置Room Database Builder
在构建你的RoomDatabase实例时,使用createFromAsset()指定初始数据库来源,再添加所有迁移规则:
@Database(entities = [YourEntity1::class, YourEntity2::class, ...], version = 4) abstract class AppDatabase : RoomDatabase() { // DAO 定义 abstract fun yourDao(): YourDao companion object { // 迁移规则 val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { // v1到v2的Schema和数据迁移逻辑 } } val MIGRATION_2_3 = object : Migration(2, 3) { override fun migrate(database: SupportSQLiteDatabase) { // v2到v3的迁移逻辑 } } val MIGRATION_3_4 = object : Migration(3, 4) { override fun migrate(database: SupportSQLiteDatabase) { // v3到v4的迁移逻辑 } } fun getInstance(context: Context): AppDatabase { return Room.databaseBuilder(context, AppDatabase::class.java, "my_app_db") .createFromAsset("databases/my_app_db_v1.db") // 加载v1初始数据库 .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4) // 添加所有迁移 .fallbackToDestructiveMigration() // 可选:迁移失败时兜底销毁重建 .build() } } }
3. 验证效果
现在全新安装App时,Room会先从assets目录加载v1版本的数据库,检测到当前数据库版本是4,就会依次执行1→2、2→3、3→4的迁移逻辑,完全和升级流程一致,完美实现你想要的开发周期。
关键注意点
- 确保v1的数据库文件结构完全匹配v1版本的Schema,否则Room会抛出异常;
- 每次更新迁移规则时,记得同步维护对应的迁移逻辑,保证数据和Schema的一致性;
fallbackToDestructiveMigration()是可选的,但建议添加,避免迁移失败导致App崩溃。
内容的提问来源于stack exchange,提问作者XZen
相关产品推荐
相关产品推荐

