简体   繁体   中英

Android - gson.toJson throws StackOverFlowError on ArrayList<OverlayItem>

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?

Looks like you are trying to serialize classes without default constructor (eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM