2016-07-19 11 views
10

Ich benutze Retrofit2 und möchte die Call.enqueue-Methode überschreiben.So machen Sie benutzerdefinierte Implementierung von Retrofit2.Call <T>

tat ich dies so weit:

Individuelle Call:

public class CustomCall<T> implements Call<T> { 

     private final Call<T> delegate; 
     //..every method has delegate method invoked in it 

Apis:

 @GET 
     CustomCall<TKBaseResponse> testConnection(@Url String customUrl); 

Aber ich halte diese Fehler bekommen:

Unable to create call adapter for CustomCall<....> 

und

Could not locate call adapter for CustomCall<....> 

Jede Art und Weise, wie kann ich dies richtig tun? Danke im Voraus!

+0

Sie zeigt den Rest des Call-Code starten können, und die komplette Fehlerprotokolle –

+0

warum brauchen u CustomCall zu schaffen?Erstellen Sie einfach eine Interface-Klasse, die einen einfachen Aufruf mit enthält, um alle Anwendungen zu erstellen, die mit einem Webservice verbunden sind, oder? – faruk

+0

Bitte werfen Sie einen Blick von hier https://github.com/saveendhiman/SampleApp/tree/master/app/src/main/java/com/sampleapp/api – Saveen

Antwort

1

Ich schreibe unten ein Beispiel, um Ihnen bei der Nachrüstung zu helfen.

Erstellen Sie Ihre Ressource so (MyResource.java).

Call<TKBaseResponse> testConnection(@@Url String customUrl); 

initialisieren Retrofit

private Resource getRetrofitResource(){ 
    //Initialize retrofit. 
    final Retrofit = .....//your code to initialize retrofit 
    return retrofit.create(MyResource.class); 
} 

Zum Aufruf enqueue (async Retrofit Anrufe) benötigen Sie zu implementieren, um Ihre Ressourcenantwort und eine Antwort-Handler weiterleiten, die die individuelle Implementierung in die enqueue Methode. Ich poste meine Implementierung von ResponseHandler neben.

public abstract class ResponseHandler<T> { 

    private static final String TAG = ResponseHandler.class.getSimpleName(); 

    private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 

    private final Context context; 

    public ResponseHandler() { 
     this(null); 
    } 

    public ResponseHandler(final Context context) { 
     this.context = context; 
    } 


    public abstract void onResponse(final T response); 

    public void onError(final ErrorResponse errorResponse) { 
     if (context == null) { 
      return; 
     } 
     Log.e(TAG, "An error occurred while invoking service. Error Code: " + errorResponse.getErrorCode() + LINE_SEPARATOR + "Message: " + errorResponse.getMessage() + LINE_SEPARATOR); 
     final AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context); 
     alertBuilder.setCancelable(true); 
     alertBuilder.setTitle(R.string.title_server_error_dialog); 
     alertBuilder.setMessage(R.string.network_error_message); 
     alertBuilder.setPositiveButton(R.string.text_ok, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(final DialogInterface dialog, final int which) { 
       dialog.dismiss(); 
      } 
     }); 
     alertBuilder.show(); 
    } 

    public void onFailure(Throwable throwable) { 
     if (context == null) { 
      return; 
     } 
     Log.e(TAG, "An error occurred while invoking service", throwable); 
     final AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context); 
     alertBuilder.setCancelable(true); 
     alertBuilder.setTitle(R.string.title_network_error_dialog); 
     alertBuilder.setMessage(R.string.network_error_message); 
     alertBuilder.setPositiveButton(R.string.text_ok, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(final DialogInterface dialog, final int which) { 
       dialog.dismiss(); 
      } 
     }); 
     alertBuilder.show(); 
    } 

} 

Erstellen Sie eine Methode behandeln Antwort.

protected <T> void handleResponse(Call<T> call, final ResponseHandler<T> responseHandler) { 
     call.enqueue(new Callback<T>() { 
      @Override 
      public void onResponse(final Call<T> call, final Response<T> response) { 
       if (response.isSuccess()) { 
       if (responseHandler != null) { 
        responseHandler.onResponse(response.body()); 
       } 
      } else { 
       final ErrorResponse errorResponse = parseError(response); 
       if (responseHandler != null) { 
        responseHandler.onError(errorResponse); 
       } 
      } 
      } 

      @Override 
      public void onFailure(final Call<T> call, final Throwable throwable) { 
       if (responseHandler != null) { 
       responseHandler.onFailure(throwable); 
      } 
      } 
     }); 
    } 

Bitte lassen Sie mich wissen, wenn Sie irgendwelche Zweifel haben.

Jetzt von Anruf Ihre Ressource wie unten.

final MyResource resource = getRetrofitResource(); 
final Call<TKBaseResponse> response = resource .testConnection("ANY_URL_OF_YOUR_CHOICE"); 
handleResponse(response, new ResponseHandler<TKBaseResponse>(){ 

public void onResponse(final TKBaseResponse response){ 
     //Do whatever you want to do here.. 
} 
    }); 
+0

Aus welcher Bibliothek ist ** Ressource **? –

+0

MyResource ist nichts anderes als eine einfache Java-Schnittstelle. Sie können dem folgenden Link folgen, um mehr zu erfahren. http://www.vogella.com/tutorials/Retrofit/article.html Ich werde versuchen, etwas Zeit zu ziehen und bereiten ein Git-Projekt für Sie vor, um eine sehr grundlegende Verwendung mit der richtigen Code-Struktur zu demonstrieren. Danke –

+0

Das beantwortet meine Frage nicht, wie ich die Enqueue-Funktion von Call

5

zuerst eine Servicemanager-Klasse erstellen -

public final class ServiceManager { 

    private static ServiceManager sServiceManager; 

    /** 
    * Gets the instance of the web services implementation. 
    * 
    * @return the singleton instance. 
    */ 
    public static ServiceManager get() { 
     if (sServiceManager == null) { 
      sServiceManager = new ServiceManager(); 
     } 
     return sServiceManager; 
    } 

    /** 
    * Creates the services for a given HTTP Url, useful when testing 
    * through multiple endpoints and unit testing 
    * 
    * @param clazz the service class. 
    * @param <T> type of the service. 
    * @return the created services implementation. 
    */ 
    public <T> T createService(Class<T> clazz) { 
     return createService(clazz, HttpUrl.parse(ServiceApiEndpoints.SERVICE_ENDPOINT)); 
    } 

    /** 
    * Creates the services for a given HTTP Url, useful when testing 
    * through multiple endpoints and unit testing 
    * 
    * @param clazz the service class. 
    * @param httpUrl the endpoint 
    * @param <T>  type of the service. 
    * @return the created services implementation. 
    */ 
    public <T> T createService(Class<T> clazz, HttpUrl httpUrl) { 
     Retrofit retrofit = getRetrofit(httpUrl); 
     return retrofit.create(clazz); 
    } 

    public <T> T createService(Class<T> clazz, Retrofit retrofit) { 
     return retrofit.create(clazz); 
    } 

    private Retrofit getRetrofit(HttpUrl httpUrl) { 
     return new Retrofit.Builder() 
       .baseUrl(httpUrl) 
       .client(createClient()) 
       .addConverterFactory(getConverter()) 
       .build(); 
    } 

    public Retrofit getPlainRetrofit(HttpUrl httpUrl) { 
     return new Retrofit.Builder() 
       .baseUrl(httpUrl) 
       .client(new OkHttpClient.Builder().build()) 
       .addConverterFactory(getConverter()) 
       .build(); 
    } 

    private Converter.Factory getConverter() { 
     return GsonConverterFactory.create(); 
    } 


    private OkHttpClient createClient() { 
     return new OkHttpClient.Builder().addInterceptor(new RequestInterceptor()).build(); 
    } 

} 

ServiceApiEndpoints ist ein Klasse-Service-Endpunkte enthält.

final class ServiceApiEndpoints { 

    public static final String SERVICE_ENDPOINT = "your_app_url"; 
} 

Eine Schnittstelle APIService

public interface APIService { 
String GET_INFO = "get_info"; 

    @GET(GET_INFO) 
    Call<ResInfo[]> getInfo(); 
} 

ResInfo Modell erstellen.

public class ResInfo { 
    private static final String FIELD_CONTENT = "content"; 

    public String getContent() { 
     return mContent; 
    } 

    public void setContent(final String content) { 
     mContent = content; 
    } 


    @SerializedName(FIELD_CONTENT) 
    private String mContent; 

    public ResInfo(){ 

    } 
} 

Rufen Sie die Anfrage.

private Call<ResInfo[]> mGetInfoAPICall; 

    APIService apiService=ServiceManager.get().createService(APIService.class); 
    mGetInfoAPICall = apiService.getInfo(); 
    mGetInfoAPICall.enqueue(new Callback<ResInfo[]>() { 
    @Override 
    public void onResponse(Call<ResInfo[]> call, Response<ResInfo[]> response) { 

    } 

    @Override 
    public void onFailure(Call<ResInfo[]> call, Throwable t) { 

    } 
});