如何为Room为抽象类编写TypeConverter?

问题描述

我想将一个对象插入数据库。它始终是下面这三个类别之一。 这对我来说完美了一段时间。但是从今天起它显示错误。当我将抽象类更改为普通类时,仅将空值列表插入数据库。 最糟糕的是它已经开始工作了... 我该怎么办?

我有一个抽象类:

public abstract class TAbstract{


public static class TClass1 extends TAbstract{
    public MyObject1 object1;
}

public static class TClass2 extends TAbstract{
    public MyObject2 object2;
}

public static class TClass3 extends TAbstract{
        public MyObject3 object3;
    }
}

TypeConverter:

@TypeConverter
public static List<TAbstract> toList(String value) {
    Type listType = new Typetoken<List<TAbstract>>() {}.getType();
    return new Gson().fromJson(value,listType);
}

@TypeConverter
public static String fromList(List<TAbstract> list) {
    Gson gson = new Gson();
    return gson.toJson(list);
}

错误

E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0
java.lang.RuntimeException: Exception while computing database live data.
    at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: java.lang.RuntimeException: Failed to invoke public models.value.TAbstract() with no args
    at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:113)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
    at com.google.gson.Gson.fromJson(Gson.java:932)
    at com.google.gson.Gson.fromJson(Gson.java:897)
    at com.google.gson.Gson.fromJson(Gson.java:846)
    at databases.Converters.toList(Converters.java:36)
    at databases.value.ValueDao_Impl$7.call(ValueDao_Impl.java:381)
    at databases.value.ValueDao_Impl$7.call(ValueDao_Impl.java:351)
    at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 
 Caused by: java.lang.InstantiationException: Can't instantiate abstract class models.value.TAbstract
    at java.lang.reflect.Constructor.newInstance(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
    at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:110)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212) 
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41) 
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82) 
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61) 
    at com.google.gson.Gson.fromJson(Gson.java:932) 
    at com.google.gson.Gson.fromJson(Gson.java:897) 
    at com.google.gson.Gson.fromJson(Gson.java:846) 
    at databases.Converters.toList(Converters.java:36) 
    at databases.value.ValueDao_Impl$7.call(ValueDao_Impl.java:381) 
    at databases.value.ValueDao_Impl$7.call(ValueDao_Impl.java:351) 
    at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818)

编辑: 当我将@TypeConverter更改为:

@TypeConverter
public static List<TAbstact> toList(String value) {
    Type listType = new Typetoken<List<TAbstact.TClass1>>() {}.getType();
    return new Gson().fromJson(value,listType);
}

它可以工作。但是仅适用于Object1,并且我想插入其他对象

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)