Retrofit method return wildcard

喜欢而已 提交于 2019-12-24 01:39:53

问题


I have an API response which is meant to generically return data for various activities of our application. In an effort to make the application as generic and flexible as possible we have setup an API to deliver a collection of URLs to utilize to create various rows on our activities. Our base object looks like:

public class BaseApiObject {

    @SerializedName("apiVersion")
    private String apiVersion = null;
    @SerializedName("totalResults")
    private Integer totalResults = null;
}

Our response for the activity looks like:

public class ActivityApiResponse extends BaseApiObject {
    @SerializedName("results")
    private List<ScreenItem> results = new ArrayList<>();
}

And the ScreenItem looks like:

public class ScreenItem extends BaseApiObject {
     @SerializedName("apiUrls")
     private List<String> apiUrls = new ArrayList<>() ;
}

I would like to be able to do something like this with retrofit:

@GET("{url}")
Call<? extends BaseApiObject> getUrl(@Path("url") String url);

We know that each request we make will return a BaseApiObject, but we are unsure of which type of object we will actually return -- and some of these URLs will return a list of many different types of objects.

We get the following error:

java.lang.IllegalArgumentException: Method return type must not include a type variable or wildcard: retrofit2.Call<? extends com.company.BaseApiObject>

Is there a way with Retrofit to handle this scenario or do I need to return the BaseApiObject, and then use a custom gson deserializer to actually return the proper object type(s)?


回答1:


In the end, I ended up needing to create my own Deserializer. I took the JsonDeserializationContext and then parsed my elements based on the type which was returned in the json response.

For instance assume my json looked like:

{ "shapes": 
  [ 
    {"type": "circle", "radius": 2},
    {"type": "rectangle", "width": 3, "height": 2},
    {"type": "triangle", "sides": [3, 4, 5]}
  ],
  "apiVersion": "0.1.0",
  "totalResults": "3"
}

In my deserializer, I would look at the type of the shapes in a loop, and do something like:

switch(jsonObject.get("type").getAsString()) {
    case "circle":
        return context.deserialize(jsonObject, Circle.class);
        break;

    case "rectangle": 
        return context.deserialize(jsonObject, Rectangle.class);
        break;

    case "triangle":
        return context.deserialize(jsonObject, Triangle.class);
        break;

    default:
        return context.deserialize(jsonObject, Shape.class);
        break; 
}


来源:https://stackoverflow.com/questions/37327048/retrofit-method-return-wildcard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!