I am trying to build a generic object named request which can hold request related to different entities.
For example , Request can be created for fitness class , employee class or contact class. Now below is the code to check whether
we have any offline data exists or not. getNonSynced
function will return the RealmResults
of data those are not synced.
i am adding that realmResults
into the request class's RealmList
. once request is created i am converting it into json string using GSON and this is the point where my app gets crashed and throwing Caused by: java.lang.StackOverflowError: stack size 8MB
Function to get offline data and parse request
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);
}
Request Class
public class Request<T> {
private RealmList<T> requestList;
public RealmList<T> getRequestList() {
return requestList;
}
public void setRequestList(RealmList<T> requestList) {
this.requestList = requestList;
}
}
This is probably happening at the time of GSON tries to serialize RealmList<T> requestList
where it might be trying to find the concrete type. All i am seeking is the way to box the class and provide appropriate class type to T
Error
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)
I have tried few things here, if i am explicitly providing a type specific object then gson does not throw error.
Request<T> request = new Request<T>();
RealmList<T> realmList = new RealmList<T>();
// explicitly providing fitness object
realmList.add((T)new Fitness());
request.setRequestList(realmList);
so i think i need to explore a way to return realm result that has specific type.
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;
}
by replacing following line to convert realm result into realm list , it started working because realmResults.subList(0, realmResults.size())
returns List<T>
and copyFromRealm
returns List<RealmModel>
From
realmList.addAll(realmResults.subList(0, realmResults.size()));
To
realmList.addAll(realm.copyFromRealm(realmResults));