首页 > 解决方案 > 在 GSON 中序列化泛型类时出现 stackoverflow 错误

问题描述

我正在尝试构建一个名为 request 的通用对象,它可以保存与不同实体相关的请求。

例如,可以为健身类、员工类或联系人类创建请求。现在下面是检查我们是否存在任何离线数据的代码。getNonSynced函数将返回RealmResults未同步的数据。

我将其添加realmResults到请求类的RealmList. 创建请求后,我将使用 GSON 将其转换为 json 字符串,这就是我的应用程序崩溃和抛出的地方Caused by: java.lang.StackOverflowError: stack size 8MB

获取离线数据和解析请求的功能

  public <T extends  RealmModel > void checkOfflineData(){


    Realm realm = Realm.getDefaultInstance();

    Set<Class<? extends RealmModel>> realmObjectClasses = realm.getConfiguration().getRealmObjectClasses();

    for(Class modelClass: realmObjectClasses) {

            // fetch non synced data 

            RealmResults realmResults = getNotSynced(realm,modelClass);
            if(realmResults !=null && realmResults.size() > 0){

                //build a request 
                Request<T> request = new Request<T>();
                RealmList<T> realmList = new RealmList<T>();
                //add results to list
                realmList.addAll(realmResults.subList(0, realmResults.size()));
                request.setRequestList(realmList);

            }
    }

    // Parsing using GSON data


    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(Request.class, new RequestSerializer());
    Gson gson = builder.create();
    String data = gson.toJson(request);



}

请求类

public class Request<T>  {

private RealmList<T> requestList;

public RealmList<T> getRequestList() {
    return requestList;
}

public void setRequestList(RealmList<T> requestList) {
    this.requestList = requestList;
}

}

这可能发生在 GSON 尝试序列化RealmList<T> requestList它可能试图找到具体类型的位置时。我所寻求的只是将课程装箱并为 T 提供适当的课程类型的方法

错误

    07-17 13:04:00.177 6076-6076/com.org.connectedhealth W/System.err: Caused by: java.lang.StackOverflowError: stack size 8MB
        at java.lang.reflect.Field.get(Native Method)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.writeField(ReflectiveTypeAdapterFactory.java:138)
07-17 13:04:00.178 6076-6076/com.org.connectedhealth W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:243)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:208)
        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:145)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127)
07-17 13:04:00.179 6076-6076/com.org.connectedhealth W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245)
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
07-17 13:04:00.180 6076-6076/com.org.connectedhealth W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127)

我在这里尝试了几件事,如果我明确提供类型特定的对象,那么 gson 不会抛出错误。

      Request<T> request = new Request<T>();
      RealmList<T> realmList = new RealmList<T>();

      // explicitly providing fitness object 
      realmList.add((T)new Fitness());
      request.setRequestList(realmList);

所以我认为我需要探索一种方法来返回具有特定类型的领域结果。

 private <T extends RealmModel> RealmResults<T> getNotSynced(Realm realm , Class<T> modelClass) {

        RealmResults<T>  realmResults =null;
        try{

            realmResults= realm.where(modelClass).equalTo("syncInfo.syncStatus", false).findAll();
        }catch (Exception e){

            Log.e(TAG ,"Exception "+e.getMessage());

        }

        return  realmResults;
    }

标签: androidrealmrealm-list

解决方案


通过替换以下行将领域结果转换为领域列表,它开始工作,因为realmResults.subList(0, realmResults.size())返回List<T>copyFromRealm返回List<RealmModel>

realmList.addAll(realmResults.subList(0, realmResults.size()));

realmList.addAll(realm.copyFromRealm(realmResults));

推荐阅读