Retrofit方法返回通配符

时间:2016-05-19 14:58:14

标签: java android retrofit retrofit2

我有一个API响应,它通常用于返回我们应用程序的各种活动的数据。为了使应用程序尽可能通用和灵活,我们设置了一个API来提供一组URL,用于在我们的活动中创建各种行。我们的基础对象如下:

public class BaseApiObject {

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

我们对该活动的回应如下:

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

ScreenItem看起来像:

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

我希望能够通过改造来做这样的事情:

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

我们知道我们发出的每个请求都会返回一个BaseApiObject,但我们不确定实际返回的对象类型 - 其中一些URL将返回许多不同类型对象的列表。

我们收到以下错误:

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

Retrofit是否有办法处理这种情况,或者我是否需要返回BaseApiObject,然后使用自定义gson反序列化器来实际返回正确的对象类型?

1 个答案:

答案 0 :(得分:1)

最后,我最终需要创建自己的Deserializer。我接受了JsonDeserializationContext,然后根据json响应中返回的类型解析了我的元素。

例如假设我的json看起来像:

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

在我的反序列化器中,我会查看循环中形状的类型,并执行以下操作:

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; 
}