-
-
Save bioyeneye/f906c7757c3ed5a9ae85971f7b5b48f6 to your computer and use it in GitHub Desktop.
How to use Retrofit in Android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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*/ | |
} | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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