请帮助T_T挖掘2天以找到解决此问题的方法!
我正在使用Retrofit在我的应用中制作一些网络任务, 我调用的其中一个API有时会返回一个不同的对象,但我知道每次调用它时它将返回什么时候以及它将返回什么。
在这种情况下,Message
是一个对象
{
"key": "some key",
"category": "some category",
"channel": "some channel",
"status": "some status",
"message": {
"someValue": "54",
"someOtherValue": "5353"
}
}
此处Message
是一个字符串
{
"key": "some key",
"category": "some category",
"channel": "some channel",
"status": "some status",
"message": "this is a string"
}
所以我试图通过使用泛型来实现这个解决方案的良好设计, 我有一个这样的通用类,
ContentResponse类
public class ContentResponse<T> {
private List<Content<T>> content = new ArrayList<Content<T>>();
//getters and setters
}
内容类
public class Content<T>
{
private String key;
private String category;
private String channel;
private String status;
private T message;
//getters and setters
}
ContentInterface类
public interface ContentInterface<T>
{
@GET("/public/content/{category}")
ContentResponse<T> getContent(@Path(PathParameters.CATEGORY) String category);
}
问题出在这里
public class ContentRequest<T> extends RetrofitSpiceRequest<ContentResponse<T>, ContentInterface<T>>
{
String category;
public ContentRequest(Class<ContentResponse<T>> clazz, Class<ContentInterface<T>> retrofittedInterfaceClass, String category) {
super(clazz, retrofittedInterfaceClass);
this.category = category;
}
@Override
public ContentResponse<T> loadDataFromNetwork() throws Exception {
return getService().getContent(category);
}
}
在此上下文中,我知道返回的对象是Map<String, String>
contentRequest = new ContentRequest(new Class<ContentResponse<Map<String, String>>>(),
new Class<ContentInterface<Map<String, String>>>(),
"appstrings");
但是我明白了!
'class()'在java.lang.Class
中不公开
我不能打电话给ContentResponse<Map<String,String>>.class
,那我该怎么办?
答案 0 :(得分:4)
这在Retrofit中是不可能的
public interface ContentInterface<T>
{
@GET("/public/content/{category}")
ContentResponse<T> getContent(@Path(PathParameters.CATEGORY) String category);
}
Retrofit在运行时使用方法的签名来确定返回Type
。在这种情况下,它将是Class
的原始ContentResponse
和ParameterizedType
T
,显然无法正常工作。
使这项工作的方法是在界面中添加ParameterizedType
,就像这样。
编辑:注意ContentInterface
T
的方式
public interface ContentInterface
{
@GET("/public/content/{category}")
ContentResponse<String> getContent(@Path(PathParameters.CATEGORY) String category);
}
但是那会失败,因为你不能拥有2个具有相同签名的方法定义。由于类型擦除,这不会编译。
public interface ContentInterface
{
@GET("/public/content/{category}")
ContentResponse<String> getContent(@Path(PathParameters.CATEGORY) String category);
ContentResponse<Map<String, String> getContent(@Path(PathParameters.CATEGORY) String category);
}
所以最后你还需要创建2种不同的方法来与2种不同类型的数据进行交互。
public interface ContentInterface
{
@GET("/public/content/{category}")
ContentResponse<String> getContentAsString(@Path(PathParameters.CATEGORY) String category);
ContentResponse<Map<String, String> getContentAsMap(@Path(PathParameters.CATEGORY) String category);
}
请参阅@JakeWharton回复here关于使用Retrofit的概括以及他们为什么不真正支持它。我相信同样的想法适用于此。