I am using Retrofit2 and I want to Override its Call.enqueue method.
I did this so far:
Custom 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);
But I keep getting these errors:
Unable to create call adapter for CustomCall<....>
and
Could not locate call adapter for CustomCall<....>
Any way on how can I do this properly? Thanks in advance!
2 Answers
Answers 1
First create a ServiceManager class -
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 is a class contains service endpoints.
final class ServiceApiEndpoints { public static final String SERVICE_ENDPOINT = "your_app_url"; }
Create an interface APIService
public interface APIService { String GET_INFO = "get_info"; @GET(GET_INFO) Call<ResInfo[]> getInfo(); }
Create ResInfo model.
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(){ } }
Call the request.
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) { } });
Answers 2
I am posting below an example to help you with retrofit implementation.
Create your resource like this (MyResource.java).
Call<TKBaseResponse> testConnection(@@Url String customUrl);
Initialize Retrofit
private Resource getRetrofitResource(){ //Initialize retrofit. final Retrofit = .....//your code to initialize retrofit return retrofit.create(MyResource.class); }
To implement call enqueue(async retrofit calls) you need to pass your resource response and a response handler which is your custom implementation into the enqueue method. I am posting my implementation of ResponseHandler alongside.
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(); } }
Create a method handle response.
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); } } }); }
Please let me know if you have any doubts around this.
Now from call your resource like below.
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 comments:
Post a Comment