1

I'm trying to create a JSON string of my ArrayList containing OverlayItems (OverlayItem is a type of osmdroid library that I'm using). The reason I'm doing this is because I want to keep this ArrayList of OverlayItems when the Android app is closed, the data must be kept (and the gson-solution seemed like a nice way of achieving this since you can't just add an ArrayList to SharedPreferences).

This throws a StackOverflowException error, I think it cannot resolve the type. I looked up my problem and many answers on other threads suggest that this is caused by a circular reference. I don't think that this is the case however with the OverlayItems, they are built like this:

OverlayItem(String aUid, String aTitle, String aDescription, IGeoPoint aGeoPoint)

IGeoPoint is also a type of osmdroid, it just holds a longitude and latitude int.

The code for the serializing is this:

SharedPreferences.Editor ed = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(waypointMarkers);
ed.putString("waypoints", json);
ed.commit();

// wayPointmarkers is the ArrayList<OverlayItem>

Why am I getting these errors?:

java.lang.StackOverflowError
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
         ...

Edit 1

I've added InstanceCreators for both OverlayItem and IGeoPoint (neither of them has a default no-args constructor):

class OverlayItemInstanceCreator implements InstanceCreator<OverlayItem> {
    public OverlayItem createInstance(Type type) {
        return new OverlayItem(null,null,null,null);
    }
}

class IGeoPointItemInstanceCreator implements InstanceCreator<IGeoPoint> {
    public IGeoPoint createInstance(Type type) {
        return new IGeoPoint() {
            @Override
            public int getLatitudeE6() {
                return 0;
            }

            @Override
            public int getLongitudeE6() {
                return 0;
            }

            @Override
            public double getLatitude() {
                return 0;
            }

            @Override
            public double getLongitude() {
                return 0;
            }
        };
    }
}

And I'm registering them with this code:

GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(OverlayItem.class, new OverlayItemInstanceCreator());
    gsonBuilder.registerTypeAdapter(IGeoPoint.class, new IGeoPointItemInstanceCreator());
    Gson gson = gsonBuilder.create();
    String json = gson.toJson(waypointMarkers);
    ed.putString("waypoints", json);

But I'm still getting the same errors. What am I doing wrong?

Fluppe
  • 479
  • 7
  • 22

1 Answers1

1

Looks like you are trying to serialize classes without default constructor (e.g. GeoPoint implementation doesn't have one). Gson can't do it without additional work (actually can, but in some quirky manner and it's unsafe).

Check out this thread, it can be helpful.

Community
  • 1
  • 1
  • I see. I assume that the gson-solution is not a good idea then in my case? I don't like the other solutions mentioned in http://stackoverflow.com/questions/7057845/save-arraylist-to-sharedpreferences – Fluppe Feb 26 '15 at 14:47
  • Hm, why not? Technically you just need to do additional work by defining InstanceCreator. All docs can be found there http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/InstanceCreator.html – Sergey Yamshchikov Feb 26 '15 at 14:54
  • I've updated my question with InstanceCreator code, do you have an idea what I'm doing wrong? – Fluppe Feb 26 '15 at 15:54
  • So, I did some tests. OverlayItem depends on Drawable. I suggest to use some simplified object to store the data. – Sergey Yamshchikov Feb 26 '15 at 20:01
  • The reason I wanted to store these OverlayItems was because they contained all the data I wanted, I need the Uid, the title, the description, and the geopoint. I guess I can make objects to hold all this data, then the Drawable dependancy should be resolved – Fluppe Feb 26 '15 at 20:05