房间类型带构造器的转换器

时间:2018-11-02 07:47:35

标签: android kotlin android-room

我有房间TypeConverter,需要向其构造函数注入参数

class RoomConverters(moshi Moshi) {

    @TypeConverter
    fun fromUserActionLog(data: UserActionLogModel): String {
        return moshi.adapter(UserActionLogModel::class.java).toJson(data)
    }

    @TypeConverter
    fun toUserActionLog(json: String): UserActionLogModel {
        return moshi.adapter(UserActionLogModel::class.java).fromJson(json)}
    }
}

但是当我无法使用构造函数将TypeConverter注释到数据库对象时;

@Database(entities = [SsidModel::class], version = 1, exportSchema = false)
@TypeConverters(RoomConverters::class)   
abstract class AppDatabase : RoomDatabase() {

    abstract fun ssidDao(): SsidDao
}

有什么办法可以做到这一点?

5 个答案:

答案 0 :(得分:2)

您可以使用版本 2.3.0-alpha03

中的构造函数参数创建Room TypeConverter。

发行说明:

Room现在具有用于提供类型转换器实例的API,例如 该应用可以控制其初始化。标记类型转换器 将提供给Room的新注释 @ProvidedTypeConverter

https://developer.android.com/jetpack/androidx/releases/room#2.3.0-alpha03

在您的情况下,您应该将@ProvidedTypeConverter添加到RoomConverter

@ProvidedTypeConverter    
class RoomConverters(moshi: Moshi)

在数据库创建时创建转换器,并将其传递给数据库生成器:

val roomConverter = RoomConverters(Moshi())
val db = Room.databaseBuilder()
         .addTypeConverter(roomConverter)
         .build()

您还可以使用DI框架,例如匕首2

答案 1 :(得分:0)

我使用dagger-android,并且遇到相同的问题。 解决方案是在创建AppDatabase时

$('div[id^="question-summary-"]')

AppDatabase是简单的RoomDatabase:

@Provides @Reusable
fun provideDatabase(context: Context, moshi: Moshi): AppDatabase = 
    Room.databaseBuilder(...).build().apply { AppDatabase.moshi = moshi }

然后在转换器中使用此伴随对象:

@Database(
    entities = [OrderEntity::class],
    version = 1,
    exportSchema = false
)
@TypeConverters(DbConverters::class)
abstract class AppDatabase : RoomDatabase() {
    companion object {
        lateinit var moshi: Moshi
    }

    abstract fun orderDao(): OrderDao
}

我想这看起来很丑,但是行得通。也许将静态/伴侣对象与class DbConverters { @TypeConverter fun orderInfoToString(orderInfo: OrderInfo?): String? = AppDatabase.moshi.adapter(OrderInfo::class.java).toJson(orderInfo) @TypeConverter fun stringToOrderInfo(value: String): OrderInfo? = AppDatabase.moshi.adapter(OrderInfo::class.java).fromJson(value) } 范围一起使用是一个坏主意。 不过,Moshi是使用AppModule中的@Reuseable范围提供的,因此基本上贯穿了整个应用程序寿命

答案 2 :(得分:0)

我甚至检查了文档以获取最新的rc版本(2.2.0-rc01),也没有办法。我认为我们不能在DatabaseBuilder中注册自定义TypeConverters是个玩笑,因此我在Google issue tracker上为此创建了一个错误。

答案 3 :(得分:0)

截至2020年8月11日,Google仍未解决此问题。同时检查这些替代方法之一。

https://issuetracker.google.com/issues/142086380 https://issuetracker.google.com/issues/121067210

答案 4 :(得分:0)

现在发布了 Room 库的 2.3.0。可以实例化 Room 类型转换器并将它们提供给数据库构建器。

@ProvidedTypeConverter 类添加 TypeConverter 注释。

@ProvidedTypeConverter
class RoomConverter(moshi Moshi) {

    @TypeConverter
    fun fromUserActionLog(data: UserActionLogModel): String {
        return moshi.adapter(UserActionLogModel::class.java).toJson(data)
    }

    @TypeConverter
    fun toUserActionLog(json: String): UserActionLogModel {
        return moshi.adapter(UserActionLogModel::class.java).fromJson(json)}
    }
}

在数据库抽象类的@TypeConverter注解中提及TypeConverter。

@Database(entities = [/* entities here */], version = 1, exportSchema = false)
@TypeConverters(RoomConverters::class)   
abstract class AppDatabase : RoomDatabase() {
    ......
    // your code here
    ......
}

现在使用databaseBuilder类的静态方法Room构建数据库,并使用addTypeConverter()方法提供TypeConverter

val roomConverter = RoomConverter(moshi)
val appDb = Room.databaseBuilder(
                            applicationContext,
                            AppDatabase::class.java, DB_NAME
                        )
                            .addTypeConverter(roomConverter)
                            .build()