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

Mur*_*ROL 5 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)}
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我不能TypeConverter用构造器注释数据库对象时;

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

    abstract fun ssidDao(): SsidDao
}
Run Code Online (Sandbox Code Playgroud)

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

Nat*_* KR 10

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

向类添加@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)}
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


m.m*_*kin 9

您可以使用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)
Run Code Online (Sandbox Code Playgroud)

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

val roomConverter = RoomConverters(Moshi())
val db = Room.databaseBuilder()
         .addTypeConverter(roomConverter)
         .build()
Run Code Online (Sandbox Code Playgroud)

您也可以使用 DI 框架,例如 Dagger2


Ser*_*rev 2

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

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

AppDatabase 是简单的 RoomDatabase:

@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
}
Run Code Online (Sandbox Code Playgroud)

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

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)
}
Run Code Online (Sandbox Code Playgroud)

我想这看起来很丑,但是很有效。也许使用具有@Reuseable作用域的静态/伴生对象是一个坏主意。不过,Moshi 是使用@SingletonAppModule 中的作用域提供的,因此基本上贯穿整个应用程序生命周期