📜 ⬆️ ⬇️

Use Retrofit 2 in the Android application

Use Retrofit 2 in the Android application


Retrofit is a library for networking that is well-known among Android developers, some even consider it a standard in some way. There are a lot of reasons for such popularity: the library perfectly supports the REST API, is easily tested and configured, and requests via the network with its help are completely simple. In this article, I will show you how to configure and use Retrofit to implement networking in your application.


Retrofit Setup


Add the following dependency to the build.gradle file:


 implementation 'com.squareup.retrofit2:retrofit:2.4.0' 

We will use Gson to convert JSON to POJO. Retrofit provides a dependency that automatically converts JSON to POJO. To do this, add another dependency to the build.gradle file:


 implementation 'com.squareup.retrofit2:converter-gson:2.3.0' 

If your application is not yet allowed to work with the network, then be sure to add the appropriate line to the AndroidManifest file:


 <uses-permission android:name="android.permission.INTERNET"/> 

After the dependencies are added, we need to write code to customize the Retrofit library.


Create a class named NetworkService :


 public class NetworkService { } 

This class must be a singleton object, so declare a static variable and a function that creates and returns a variable of the same type as the class. If you do not know how this pattern works, then read this article , which has examples of implementation in the Java language.


 public class NetworkService { private static NetworkService mInstance; public static NetworkService getInstance() { if (mInstance == null) { mInstance = new NetworkService(); } return mInstance; } } 

For testing, we use JSONPlaceholder , which provides a fake online REST API for developers:


 https://jsonplaceholder.typicode.com 

Now we will declare and initialize Retrofit in the NetworkService constructor:


 public class NetworkService { private static NetworkService mInstance; private static final String BASE_URL = "https://jsonplaceholder.typicode.com"; private Retrofit mRetrofit; private NetworkService() { mRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static NetworkService getInstance() { if (mInstance == null) { mInstance = new NetworkService(); } return mInstance; } } 

Setup is complete, now we need to define the endpoints that will return data.


Add endpoints


Create an interface called JSONPlaceHolderApi :


 public interface JSONPlaceHolderApi { } 

On the JSONPlaceHolder website , the URL /posts/id is the endpoint that returns a post with the appropriate id. This endpoint accepts a GET request and returns the data in JSON format as follows:


 { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" } 

First we will create the corresponding POJO for the JSON response:


 public class Post { @SerializedName("userId") @Expose private int userId; @SerializedName("id") @Expose private int id; @SerializedName("title") @Expose private String title; @SerializedName("body") @Expose private String body; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } } 

As you can see, this is a simple POJO class. We annotated the variables with @SerializedName() , passing the name there. These names are actually keys in the JSON data returned from the API, so you can change the name of the variable as you like, but make sure that the name passed to the @SerializedName() annotation is exactly present in JSON.


In the interface created above, define the end points with the required parameters:


 public interface JSONPlaceHolderApi { @GET("/posts/{id}") public Call<Post> getPostWithID(@Path("id") int id); } 

Since we are sending a GET request, we need to apply the @GET annotation to the method, inside which there is an endpoint to which we want to send a request. As you can see, we are not adding the full URL, because Retrofit will automatically take the BASE_URL passed to the NetworkService class and add it to the rest of the URL.


The return type of the method is called Call<Post> . Call is a class provided directly by the library itself. And all methods in the interface should return values ​​of this type. This is a generic class that accepts the type of object that we want to convert to JSON. We passed Post , because this is exactly the object that we want to convert the JSON response to. We passed an integer to the parameters and annotated it with the help of @Path , inside which we wrote the id . Retrofit will take this value and at the end point replace {id} . Thus, if we pass the value of 1 as a parameter, then the end point will look like this - /posts/1 , if we pass the value of 10, then the end point will be - /posts/10 .


Now we need Retrofit to provide an implementation of the JSONPlaceHolderApi interface. To do this, use the create() method:


 public class NetworkService { private static NetworkService mInstance; private static final String BASE_URL = "https://jsonplaceholder.typicode.com"; private Retrofit mRetrofit; private NetworkService() { mRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static NetworkService getInstance() { if (mInstance == null) { mInstance = new NetworkService(); } return mInstance; } public JSONPlaceHolderApi getJSONApi() { return mRetrofit.create(JSONPlaceHolderApi.class); } } 

Next, you need to get JSONPlaceHolderApi from NetworkService and send a request:


 NetworkService.getInstance() .getJSONApi() .getPostWithID(1) .enqueue(new Callback<Post>() { @Override public void onResponse(@NonNull Call<Post> call, @NonNull Response<Post> response) { Post post = response.body(); textView.append(post.getId() + "\n"); textView.append(post.getUserId() + "\n"); textView.append(post.getTitle() + "\n"); textView.append(post.getBody() + "\n"); } @Override public void onFailure(@NonNull Call<Post> call, @NonNull Throwable t) { textView.append("Error occurred while getting request!"); t.printStackTrace(); } }); 

The returned Call object contains a method called enqueue , which accepts Callback<T> as its parameter. In onResponse we get the result Response<Post> containing the Post object returned from the server. To get the Post object itself, use the response.body() method. The rest of the code is understandable without further explanation.


Sending various types of requests


The JSONPlaceHolder API has many different endpoints that you can use.


Getting a list of messages


 @GET("/posts") public Call<List<Post>> getAllPosts(); 

To get a list of all messages, we changed the end point and the return type of the function.


Sending request with parameter


If you want to send a request with a parameter, you just need to use the @Query() annotation for the corresponding parameter in the method:


 @GET("/posts") public Call<List<Post>> getPostOfUser(@Query("userId") int id); 

Therefore, if we pass the value 6 in the method parameter, the end point will be next - /posts?userId=6 .


Sending a POST request


To send a POST request, you just need to change the method annotation.


 @POST("/posts") public Call<Post> postData(@Body Post data); 

To form the request body for this method, we use the @Body annotation for the passed parameter. Retrofit will use Gson to convert @Body to JSON.


There are several different types of queries that you can use, but this is a topic for a separate article.


Intercept requests


Retrofit provides a way to capture requests and log them to Logcat. Let's set up an interceptor and look at this magic. Add the following dependency to the build.gradle file:


 implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0' 

Update the NetworkService class this way:


 public class NetworkService { private static NetworkService mInstance; private static final String BASE_URL = "https://jsonplaceholder.typicode.com"; private Retrofit mRetrofit; private NetworkService() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient.Builder client = new OkHttpClient.Builder() .addInterceptor(interceptor); mRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(client.build()) .build(); } public static NetworkService getInstance() { if (mInstance == null) { mInstance = new NetworkService(); } return mInstance; } public JSONPlaceHolderApi getJSONApi() { return mRetrofit.create(JSONPlaceHolderApi.class); } } 

Now, when you send or receive a request, all its data, including URLs, headers, body, will be displayed in the log:


 D/OkHttp: <-- 200 https://jsonplaceholder.typicode.com/posts/1 (3030ms) date: Tue, 24 Apr 2018 15:25:19 GMT content-type: application/json; charset=utf-8 set-cookie: __cfduid=d16d4221ddfba20b5464e6829eed4e3d11524583519; expires=Wed, 24-Apr-19 15:25:19 GMT; path=/; domain=.typicode.com; HttpOnly x-powered-by: Express vary: Origin, Accept-Encoding access-control-allow-credentials: true cache-control: public, max-age=14400 pragma: no-cache expires: Tue, 24 Apr 2018 19:25:19 GMT 04-24 15:25:16.204 7023-7056/com.thetehnocafe.gurleensethi.retrofitexample D/OkHttp: x-content-type-options: nosniff etag: W/"124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU" via: 1.1 vegur cf-cache-status: HIT expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 410994f328963066-SIN 04-24 15:25:16.246 7023-7056/com.thetehnocafe.gurleensethi.retrofitexample D/OkHttp: { 04-24 15:25:16.247 7023-7056/com.thetehnocafe.gurleensethi.retrofitexample D/OkHttp: "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" } <-- END HTTP (292-byte body) 

This is where our article ends. You can find the code for this project on GitHub .


')

Source: https://habr.com/ru/post/429058/


All Articles