当前位置: 代码迷 >> Android >> 使用Gson序列化对RealmObjects的继承进行合成
  详细解决方案

使用Gson序列化对RealmObjects的继承进行合成

热度:95   发布时间:2023-08-04 11:53:38.0

我出于各种原因正在考虑将Realm作为数据库解决方案,但是目前最大的问题是Nougat中抛出的TransactionTooLargeException已经使它成为现实,因此我不得不基于ActiveAndroid重新设计当前的数据库体系结构,该体系结构有其自身的烦人局限性。 困难之处在于,Realm不支持继承( ),并且他们似乎并没有特别急于解决继承问题。 相反,他们建议使用合成而不是继承,但是我不知道如何通过Gson / Json反序列化来实现这一点。

例:

超类:动物,子类为“狗”和“德国牧羊犬”

public class Animal {

    private int numLegs;

    private boolean hasFur;
}

public class Dog extends Animal {
    private String color;

    private boolean canDoTricks;
}

public class GermanShepherd extends Dog {

    public boolean isGuardDog;

    public boolean isAtRiskOfHipDysplasia()
}

(很抱歉,这是一个超级罐头示例,仅供说明)。

现在让我们说这个的json看起来像:

{
  "numLegs" : 4,
  "hasFur" : true,
  "color" : "Black & Brown",
  "canDoTricks" : true,
  "isGuardDog" : true,
  "isAtRiskofHipDysplasia" : false
}

现在,我无法修改Json,因为它是向我提供的API。

看着这个答案: : ,似乎有可能以一种非常骇人听闻的方式使它工作,但是答案指出存在一些限制,包括序列化将错误。 由于服务器仅以不涉及疯狂合成的json格式进行通话,因此存在问题。

我可以编写自定义的Gson解串器/序列化器来完成这项工作吗? 如果是这样,那会是什么样? 我基本上需要能够将json负载转换为最多N个对象,其中N-1个对象嵌套在基础对象内。

因此,使用组合(请注意,这不一定是“ Realm”组合,因为它看起来像Realm必须使用某种怪异的接口组合形式),因此,我将拥有一个类似于以下的类:

public class GermanShepherd {
    public Animal animal;
    public Dog dog;

   // Generate a bunch of delegate methods here
}

我在树上叫错了吗? 感觉Realm可能不适用于我想做的事,并且继承已内置到我在多个地方使用的API中,尤其是在我要保留的对象中,因此我必须找出一种解决方法或使用其他解决方案。 ActiveAndroid(我现在使用的是什么)也不是理想的解决方案,我讨厌死于处理死锁,崩溃,在后台线程上查询,如果数据太大而无法传递,则会导致崩溃。意图等... SQLite的所有问题。 我愿意回答主要问题或可以解决该问题的替代方案。 在此先感谢您的帮助!

您应该为每个扁平化的具体类创建一个新的RealmObject类,并将您的JSON表示映射到它们。

要保留继承,可以通过从相互继承的接口继承getter / setter来模拟继承。

public interface IAnimal extends RealmModel {    
    int getNumberOfLegs();
    void setNumberOfLegs(int legs);
    boolean getHasFur();
    void setHasFur(boolean hasFur);
}

public interface IDog extends IAnimal {
    String getColor();
    void setColor(String color);
    boolean getCanDoTricks();
    void setCanDoTricks();
}

public interface IGermanShepherd extends IDog {
    boolean getIsGuardDog();
    void setIsGuardDog(boolean isGuardDog);
    boolean getIsAtRiskOfHipDysplasia();
    void setIsAtRiskOfHipDysplasia(boolean isAtRisk);
}

因为那样你就可以

public class GermanShepard 
    extends RealmObject 
    implements IGermanShepard {
      private int numLegs;
      private boolean hasFur;
      private String color;
      private boolean canDoTricks;
      private boolean isGuardDog;
      private boolean isAtRiskofHipDysplasia;

      // inherited getters/setters
}

您甚至可以使用它来制作存储库类

public abstract class AnimalRepository<T extends IAnimal> {
     protected Class<T> clazz;

     public AnimalRepository(Class<T> clazz) {
         this.clazz = clazz;
     }

     public RealmResults<T> findAll(Realm realm) {
         return realm.where(clazz).findAll();
     }
}

 @Singleton
 public class GermanShepardRepository extends AnimalRepository<GermanShepard> {
      @Inject
      public GermanShepardRepository() {
          super(GermanShepard.class);
      }
 }

接着

@Inject
GermanShepardRepository germanShepardRepository;

RealmResults<GermanShepard> results = germanShepardRepository.findAll(realm);

但是您确实可以将它们合并为一个类,然后为其提供String type; 参数以了解其原始类型。 这可能比拥有所有这些GermanShepards还要好。