2014-09-02 3 views
2

Помогите, пожалуйста, T_T выкопать в течение 2 дней для решения этой проблемы!Использование RoboSpice/Retrofit с параметризованными типами для ответа JSON

Я использую модификацию для выполнения некоторых сетевых задач в своем приложении, Один из 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"); 

но я получаю это !!

'класс()' не является публичной в java.lang.Class

Я не могу просто позвонить ContentResponse<Map<String,String>>.class, так что я могу здесь делать?

ответ

3

Это не представляется возможным в Модернизированный

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

дооснащения использует подпись метода во время выполнения для определения рентабельности Type. В этом случае это будет необработанный ClassContentResponse и с ParameterizedTypeT, который, очевидно, не сработает.

Способ сделать эту работу заключается в том, чтобы добавить ParameterizedType в интерфейс так. EDIT: Заметьте, как 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 разных метода для взаимодействия с двумя различными типами данных.

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 о генерализации с Модернизированный и почему они на самом деле не поддерживают его. Я считаю, что к этому относится и то же самое.

+0

Спасибо за очень подробный ответ :) , поэтому я создам несколько методов для каждого типа ответа, но как бы получить тип параметризованного «ContentResponse» для моего ContentRequest? –

+0

Поскольку интерфейс ContentInterface больше не использует тип 'T', вы можете просто передать ContentInterface.class. 'contentRequest = новый ContentRequest (/ * не знаю, как это используется * /, ContentInterface.class, "appstrings");' –

+0

Вы правы, но ContentRequest берет 2 Params (класс responseType, класс retrofitInterface) , первый параметр - ожидаемый тип ответа, что я должен передать в случае, когда я ожидаю ContentResponse >? –

Смежные вопросы