【问题标题】:Using RoboSpice/Retrofit with Parametrized types for JSON Response将 RoboSpice/Retrofit 与参数化类型一起用于 JSON 响应
【发布时间】:2014-10-26 12:19:04
【问题描述】:

请帮忙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&lt;String, String&gt;

    contentRequest = new ContentRequest(new Class<ContentResponse<Map<String, String>>>(),
new Class<ContentInterface<Map<String, String>>>(),
"appstrings");

但我明白了!!

'class()' 在 java.lang.Class 中不公开

我不能只打电话给ContentResponse&lt;Map&lt;String,String&gt;&gt;.class,我可以在这里做什么?

【问题讨论】:

    标签: java android json generics retrofit


    【解决方案1】:

    这在改造中是不可能的

    public interface ContentInterface<T>
    {
        @GET("/public/content/{category}")
        ContentResponse<T> getContent(@Path(PathParameters.CATEGORY) String category);
    }
    

    Retrofit 在运行时使用方法的签名来确定返回Type。在这种情况下,它将是 ContentResponse 的原始 ClassTParameterizedType,这显然是行不通的。

    实现这一点的方法是像这样在界面中添加ParameterizedType。 编辑:注意ContentInterface 不再使用T 输入

    public interface ContentInterface
    {
        @GET("/public/content/{category}")
        ContentResponse<String> getContent(@Path(PathParameters.CATEGORY) String category);
    }
    

    但是这违背了目的,因为你不能有两个具有相同签名的方法定义。由于类型擦除,这不会编译。

    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 的泛化以及他们为什么不真正支持它。我相信同样的想法也适用于此。

    【讨论】:

    • 感谢您提供非常详细的答案 :) 所以我将为每种类型的响应创建多种方法,但是如何为我的 ContentRequest 获取参数化“ContentResponse”的类型?
    • 由于 ContentInterface 接口不再使用 T 类型,您可以简单地传递 ContentInterface.class。 contentRequest = new ContentRequest(/*not sure how this is used*/, ContentInterface.class, "appstrings");
    • 你是对的,但是 ContentRequest 需要 2 个参数(Class responseType, Class retrofitInterface),第一个参数是预期的响应类型,我应该传递什么以防万一我期待 ContentResponse> ?
    • 我不确定您的RetrofitSpiceRequest 是如何实现的,但是传递响应的类将不起作用。基本上现在你需要有 2 个loadDataFromNetwork 方法。一种用于ContentResponse&lt;String&gt;,一种用于ContentResponse&lt;Map&lt;String,String&gt;&gt;
    • 经过这么长时间,我决定放弃 robospice 并开始使用 RxJava 研究 Retrofit :)
    猜你喜欢
    • 2015-06-30
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2020-09-22
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多