改造方法 return 通配符
Retrofit method return wildcard
我有一个 API 响应,它一般用于我们应用程序的各种活动的 return 数据。为了使应用程序尽可能通用和灵活,我们设置了一个 API 来提供一组 URL,用于在我们的活动中创建各种行。我们的基础对象看起来像:
public class BaseApiObject {
@SerializedName("apiVersion")
private String apiVersion = null;
@SerializedName("totalResults")
private Integer totalResults = null;
}
我们对 activity 的回复如下:
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);
我们知道我们发出的每个请求都将 return 一个 BaseApiObject,但我们不确定我们实际上 return 是哪种类型的对象——其中一些 URL 将 return 许多不同类型对象的列表。
我们收到以下错误:
java.lang.IllegalArgumentException: Method return type must not include a type variable or wildcard: retrofit2.Call<? extends com.company.BaseApiObject>
Retrofit 是否有办法处理这种情况,或者我是否需要 return BaseApiObject,然后使用自定义 gson 反序列化器来实际 return 正确的对象类型?
最后,我最终需要创建自己的反序列化器。我获取了 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;
}
我有一个 API 响应,它一般用于我们应用程序的各种活动的 return 数据。为了使应用程序尽可能通用和灵活,我们设置了一个 API 来提供一组 URL,用于在我们的活动中创建各种行。我们的基础对象看起来像:
public class BaseApiObject {
@SerializedName("apiVersion")
private String apiVersion = null;
@SerializedName("totalResults")
private Integer totalResults = null;
}
我们对 activity 的回复如下:
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);
我们知道我们发出的每个请求都将 return 一个 BaseApiObject,但我们不确定我们实际上 return 是哪种类型的对象——其中一些 URL 将 return 许多不同类型对象的列表。
我们收到以下错误:
java.lang.IllegalArgumentException: Method return type must not include a type variable or wildcard: retrofit2.Call<? extends com.company.BaseApiObject>
Retrofit 是否有办法处理这种情况,或者我是否需要 return BaseApiObject,然后使用自定义 gson 反序列化器来实际 return 正确的对象类型?
最后,我最终需要创建自己的反序列化器。我获取了 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;
}