Skip to content

Instantly share code, notes, and snippets.

@cutiko
Last active October 29, 2018 05:16
Show Gist options
  • Save cutiko/e8b75896ae12aff9fc580f33fb310e7e to your computer and use it in GitHub Desktop.
Save cutiko/e8b75896ae12aff9fc580f33fb310e7e to your computer and use it in GitHub Desktop.
How to use Retrofit in Android
public clas AsyncImplementation extends AsyncTask<Void, Void, Void> {
/*Please read the rest of the explanation in the DefaultImplementation.java file. The difference between a default http request
and one using an AsyncTask is the enqeue() or the .execute() method*/
/*If you are passing params to the url, like it would be the case of the method post(long theDynamicParameter) you can
do it using replacing the void in the AsyncTask, in this case we are passing a Map so is passed in the constructor. Some times,
you would want the AsyncTask solve all the logic, then implements methods here to do it. Create the request http in a loop.
Use getter and setter to extends this to another class, etc.
Now in activity you can new AsyncImplementation(map).execute();*/
private Map<String, String> map;
public AsyncImplementation(Map<String, String> map) {
this.map = map;
}
@Override
protected Integer doInBackground(Void... voids) {
Requests request = Interceptors.getInterceptor().aCommonGetInterceptor();
Call<ArrayOfModel[]> call = request.get(map);
try {
Response<ArrayOfModel[]> response = call.execute();
/*You have your response do what ever you want. Tip:*/
ArrayOfModel[] arrayOfModel = response.body();
} catch (IOException e) {
/*Something went wrong*/
}
return null;
}
}
public class DefaultImplementation {
/*There are 2 implementations, the first is using the Retrofit default callback and the second one is done by
controlling the thread using an AsyncTask. Most of the times, a login can be done with a simple default callback,
but more heavy gets should be done in the background. If for any reason you want to write objects in the Android database,
you have to use the AsyncTask, otherwise UI will freeze*/
public void postUsingDefaultCallback(String firstField, String secondField) {
Requests request = new Interceptors().theMostBasicInterceptor();
Call<SomeModel> call = request.postRequest(firstField, secondField);
call.enqueue(new Callback<SomeModel>() {
@Override
public void onResponse(Call<SomeModel> call, Response<SomeModel> response) {
int code = response.code();
}
@Override
public void onFailure(Call<UserInfo> call, Throwable t) {
/*If you are doing this inside an activity then onFailure and onResponse can access the UI.
If you are doing this in another class that is not an activity neither a fragment, then pass
an interface in the constructor of the class so you can deliver result back*/
}
});
}
}
public class Interceptors {
private static final String BASE_URL = "http://www.yourfancyurl.com/can/have/more_url/";
/*If you are gonn use this a lot, then the class should be a Singleton, creating the interceptor is a heavy process reuse it*/
/*Please notice that the method is from the same type than the interface*/
public Requests theMostBasicInterceptor() {
Retrofit interceptor = new Retrofit.Builder()
.baseUrl(BASE_URL)
/*Never forget about adding the converter, otherwise you can not parse the data*/
.addConverterFactory(GsonConverterFactory.create())
.build();
Requests someRequest = interceptor.create(Requests.class);
/*The interceptor must return an interface, is the same interface where you wrote the methods for the request http*/
return someRequest;
}
public Request basicVariation() {
//Same basic interceptor than above, but this time we add a longer wait before time out, in case our server is slow
OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS);
OkHttpClient client = httpClient.build();
Retrofit interceptor = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Requests request = interceptor.create(Requests.class);
return request;
}
public Requests aCommonGetInterceptor() {
/*This is very common in gets cause increase the response time wait and add headers and does retrys*/
OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request request = originalRequest.newBuilder()
/*Common headers*/
.header("authtoken", "YOUR_AUTHTOKEN_REPLACE_THIS")
.header("Accept", "application/json")
/*Custom header*/
.header("Flavor", "mint")
.build();
Response response = chain.proceed(request);
/*If the request fail then you get 3 retrys*/
int retryCount = 0;
while (!response.isSuccessful() && retryCount < 3) {
retryCount++;
response = chain.proceed(request);
}
return response;
}
});
OkHttpClient client = httpClient.build();
Retrofit interceptor = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Request request = interceptor.create(Requests.class);
return request;
}
public Requests commonPostInterceptor() {
/*Mostly the same of what is done with post, but this time the waiting time for response after post is increase
and, very important, there are no retry. Here there is a 1 min waiting period, if for any reason the server did
got processed the request but took 1 min and 1 sec to response, you dont want to retry cause it would create
another object duplicated. One min waiting time for a server is a lot, it should work with this basis. If it doesnt
then dont make it worse by doing retry*/
OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("authtoken", "YOUR_AUTHTOKEN_REPLACE_THIS")
.header("Music", "loud")
.build();
Response response = chain.proceed(request);
return response;
}
});
OkHttpClient client = httpClient.build();
Retrofit interceptor = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Requests service = interceptor.create(Requests.class);
return service;
}
}
public interface Requests {
@FormUrlEncoded
@POST("some_relative_url")
Call<SomeModel> postRequest(@Field("first_field") String firstField, @Field("secondField") String secondField);
@GET("another_relative_url")
Call<ArrayOfModel[]> get(@QueryMap Map<String, String> queryMap);
@POST("relative/{THIS_IS_A_DYNAMIC_PARAMETER}/relative_again")
Call<TheModel> post(@Path("THIS_IS_A_DYNAMIC_PARAMETER") long theDynamicParameter);
@FormUrlEncoded
@PUT("relative/url")
Call<SomeModel> put(@Field("name_of_the_field") String nameOfTheField);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment