Can I use one single TypeConverter for different o

2019-08-28 18:44发布

So far for storing in Room Database I've been using type converter for each classes. Like this:

@SerializedName("sidebar")
@Expose
@TypeConverters(SidebarConverter.class)
private Sidebar sidebar;
@SerializedName("splash")
@Expose
@TypeConverters(SplashConverter.class)
private Splash splash;
@SerializedName("overview")
@Expose
@TypeConverters(OverviewConverter.class)
private Overview overview;
@SerializedName("home")
@Expose
@TypeConverters(HomeConverter.class)
private Home home;
@SerializedName("portfolio")
@Expose
@TypeConverters(PortfolioConverter.class)
private Portfolio portfolio;
@SerializedName("team")
@Expose
@TypeConverters(TeamConverter.class)
private Team team;

I want to know if there's a more convenient way to use one TypeConverter single handedly in Database.

2条回答
再贱就再见
2楼-- · 2019-08-28 19:22

The issue here is that Room's code generation tries to find specific type, and if you try to make a generic converter it fails to generate appropriate methods. However, if in your case it's appropriate to transfrom data to json for storage, you can reduce boilerplate like this:

@TypeConverter
fun toSomething(value: String): Something = fromJson(value)

@TypeConverter
fun fromSomething(value: Something): String = toJson(value)

fromJson and toJson are generic, for example they can look like this. Any time you need to add types, just take two methods above and replace 'Something' with your type. If you have a lot of classes to convert, you can even code-gen TypeConverters like this pretty easily to satisfy Room's code-gen needs.

inline fun <reified T> fromJson(value: String): T {
    val jsonAdapter = moshi.adapter(T::class.java)
    return jsonAdapter.fromJson(value)
}

inline fun <reified T> toJson(value: T): String {
    val jsonAdapter = moshi.adapter(T::class.java)
    return jsonAdapter.toJson(value)
}
查看更多
Melony?
3楼-- · 2019-08-28 19:27

You can define all your converter in a Single Class like this:

public class DateTypeConverter {

    @TypeConverter
    public static Date toDate(Long value) {
        return value == null ? null : new Date(value);
    }

    @TypeConverter
    public static Long toLong(Date value) {
        return value == null ? null : value.getTime();
    }
}

And then set this converter on your Room Database with @TypeConverter annotation like this which work globally on any @Entity class.You don't need to define @TypeConverter Individually in Entity class

@Database(entities = {Product.class}, version = 1)
@TypeConverters({DateTypeConverter.class})
public abstract class MyDatabase extends RoomDatabase {
    public abstract ProductDao productDao();
}

Note we’ve added a new annotation named @TypeConverters in our database definition in order to reference the different converters that we can have (you can separate it by commas and add others).

查看更多
登录 后发表回答