Android Room自动迁移中如何传入Context实现数据转换?
在Room自动迁移中为AutoMigrationSpec传入Context的解决方案
直接通过带参构造函数给AutoMigrationSpec实现类传入Context是不可行的——Room在生成自动迁移代码时,会默认使用无参构造实例化你的AutoMigrationSpec类,带参构造会导致编译错误。以下是两种可行的解决方案:
方案1:使用全局Application Context(最简单直接)
通过Application类持有全局的Application Context,在迁移逻辑中直接调用:
步骤1:定义Application类
public class MyApplication extends Application { private static Context sAppContext; @Override public void onCreate() { super.onCreate(); sAppContext = getApplicationContext(); } public static Context getAppContext() { return sAppContext; } }
记得在AndroidManifest.xml中指定该Application类:
<application android:name=".MyApplication" <!-- 其他配置属性 --> > </application>
步骤2:修改AutoMigration实现类
public class MyAutoMigration implements AutoMigrationSpec { @Override public void onPostMigrate(SupportSQLiteDatabase database) { // 获取全局Application Context Context context = MyApplication.getAppContext(); // 从assets读取数据并执行转换逻辑 try (InputStream inputStream = context.getAssets().open("migration_data.json")) { // 示例:读取并解析JSON数据 String jsonContent = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); // 执行数据库数据转换操作,比如插入或更新 database.execSQL("UPDATE target_table SET column = ? WHERE id = ?", new Object[]{jsonContent, 1}); } catch (IOException e) { e.printStackTrace(); // 处理读取失败的异常 } } }
方案2:使用依赖注入(以Hilt为例,适用于已集成DI的项目)
如果项目已使用Hilt进行依赖注入,可通过注解让Room自动获取带Context的AutoMigrationSpec实例:
步骤1:为AutoMigrationSpec添加@Inject构造
public class MyAutoMigration implements AutoMigrationSpec { private final Context mContext; @Inject public MyAutoMigration(@ApplicationContext Context context) { this.mContext = context; } @Override public void onPostMigrate(SupportSQLiteDatabase database) { // 使用mContext读取assets数据并执行转换,逻辑同方案1 } }
步骤2:配置RoomDatabase并通过Hilt提供实例
@Database( entities = {YourEntity.class}, version = 2, autoMigrations = { @AutoMigration( from = 1, to = 2, spec = MyAutoMigration.class ) } ) @TypeConverters(YourTypeConverters.class) public abstract class AppDatabase extends RoomDatabase { public abstract YourDao yourDao(); }
在Hilt模块中提供RoomDatabase实例:
@Module @InstallIn(SingletonComponent.class) public class DatabaseModule { @Provides @Singleton public AppDatabase provideAppDatabase(@ApplicationContext Context context) { return Room.databaseBuilder(context, AppDatabase.class, "app_database") .build(); } }
注意事项
- 必须使用Application Context,禁止传入Activity/Fragment的Context,避免引发内存泄漏。
- 方案1中要确保Application类被正确初始化,防止出现空指针异常。
- 使用依赖注入时,需保证Hilt配置正确,确保Room能获取到
AutoMigrationSpec的实例。
内容的提问来源于stack exchange,提问作者VJe
相关产品推荐
相关产品推荐

