Android Room:手动提供带@ProvidedTypeConverter的TypeConverter抛出运行时错误
Room数据库TypeConverter手动实例化报错问题
代码实现
自定义TypeConverter
@ProvidedTypeConverter class BackgroundTasksMemoryConverter( private val gson: Gson, ) { @TypeConverter fun fromString(serialized: String): BackgroundTasksMemoryDb { return gson.fromJson(serialized, BackgroundTasksMemoryDb::class.java) } @TypeConverter fun toString(dataStructure: BackgroundTasksMemoryDb): String { return gson.toJson(dataStructure) } }
数据库构建代码
myRoomDatabase = Room.databaseBuilder( context, MyRoomDatabase::class.java, DatabaseConstants.DATABASE_NAME ).apply { addTypeConverter(BackgroundTasksMemoryConverter(gson)) }.build()
Room数据库定义
@Database( entities = [ BackgroundTasksMemoryDb::class ], version = 1 ) @TypeConverters( value = [ BackgroundTasksMemoryConverter::class, ] ) internal abstract class MyRoomDatabase : RoomDatabase() { abstract val backgroundTasksMemoryDao: BackgroundTasksMemoryDao }
报错信息
FATAL EXCEPTION: main Process: com.techyourchance.android.debug, PID: 30902 java.lang.IllegalArgumentException: Unexpected type converter com.techyourchance.android.database.converters.BackgroundTasksMemoryConverter@29dc933. Annotate TypeConverter class with @ProvidedTypeConverter annotation or remove this converter from the builder.
问题原因与解决方案
问题出在同时使用了两种TypeConverter注册方式:
- 你给转换器加了
@ProvidedTypeConverter,本意是告诉Room该转换器的实例由外部提供,不需要Room自行创建,因此在数据库builder里用addTypeConverter()手动传入实例的逻辑是对的。 - 但你又在
MyRoomDatabase的@TypeConverters注解里声明了这个转换器类,这会让Room尝试自行实例化它,两种注册逻辑冲突导致报错。
修复方案二选一:
- 保留手动实例化方式:删除
MyRoomDatabase类上@TypeConverters注解里的BackgroundTasksMemoryConverter::class,只保留builder中的addTypeConverter()调用,Room会直接使用你提供的实例。 - 改用Room自动实例化:如果想通过
@TypeConverters注解注册,需要去掉@ProvidedTypeConverter注解,同时给转换器类添加无参构造方法(若使用Dagger等依赖注入框架,也可通过构造注入让Room获取实例),并删除builder里的addTypeConverter()调用。
内容的提问来源于stack exchange,提问作者Vasiliy
相关产品推荐
相关产品推荐

