📜 ⬆️ ⬇️

Retrofit on Android with Kotlin

image


One of the most exciting ads on Google I / O this year was Kotlin’s official support for Android development.


Kotlin is not really a new language, he is already> 5 years old and he is quite mature. Here you can get more information about the language.


I plan to share some "practices" of using Kotlin in the development of Android.


Retrofit is a very popular library for working with the network, and it is widely used in the developer community. Even Google uses it in its code samples.


In this article I will discuss how to use the REST API in your applications using Retrofit + Kotlin + RxJava. We will use the Github API to get a list of Java developers in Omsk, Russia. Also, I’ll touch on some of the features of a programming language and tell you how we can apply them to what we, Android developers, do every day - to call the API.


0. Installation


Android Studio 3.0 (Preview) now has built-in support for Kotlin, without manual installation of plug-ins. From here you can install a preview version.


1. Add dependencies


To use Retrofit , you need to add dependencies to the build.gradle file:


dependencies { // retrofit compile "com.squareup.retrofit2:retrofit:2.3.0" compile "com.squareup.retrofit2:adapter-rxjava2:2.3.0" compile "com.squareup.retrofit2:converter-gson:2.3.0" // rxandroid compile "io.reactivex.rxjava2:rxandroid:2.0.1" } 

RxJava2 will help make our calls reactive.
The GSON converter will process the deserialization and serialization of the request and response bodies.
RxAndroid will help us with binding RxJava2 to Android.


2. Creating data classes


As a rule, the next step is to create data classes that are POJOs (Plain Old Java Objects) and that will represent responses to API calls.


With the Github API, users will be presented as objects.


How it will look on Kotlin:


 data class User( val login: String, val id: Long, val url: String, val html_url: String, val followers_url: String, val following_url: String, val starred_url: String, val gists_url: String, val type: String, val score: Int ) 

Classes of data in Kotlin


Kotlin data classes are classes specifically designed for data storage.


The Kotlin compiler automatically helps us implement the equals () , hashCode () and toString () methods in the class, which makes the code even shorter because we don’t have to do it ourselves.


We can override the default implementation of any of these methods by defining a method.


A great feature is that we can create search results in a single Kotlin file - say, SearchResponse.kt . Our final search response class will contain all the associated data classes and look like this:


SearchResponse.kt


 data class User( val login: String, val id: Long, val url: String, val html_url: String, val followers_url: String, val following_url: String, val starred_url: String, val gists_url: String, val type: String, val score: Int ) data class Result (val total_count: Int, val incomplete_results: Boolean, val items: List<User>) 

3. Creating API


The next step we usually do in Java is to create an API that we will use to create requests and receive responses.


As a rule, in Java, I would like to create a convenient "factory" class that creates an API service when needed, and I would do something like this:


GithubApiService.java


 public interface GithubApiService { @GET("search/users") Observable<Result> search(@Query("q") String query, @Query("page") int page, @Query("per_page") int perPage); /** * Factory class for convenient creation of the Api Service interface */ class Factory { public static GithubApiService create() { Retrofit retrofit = new Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl("https://api.github.com/") .build(); return retrofit.create(GithubApiService.class); } } } 

To use this interface, we make the following calls:


 GithubApiService apiService = GithubApiService.Factory.create(); apiService.search(/** search parameters go in here **/); 

To repeat the same thing in Kotlin, we will have an equivalent GithubApiService.kt interface that will look like this:


GithubApiService.kt


 interface GithubApiService { @GET("search/users") fun search(@Query("q") query: String, @Query("page") page: Int, @Query("per_page") perPage: Int): Observable<Result> /** * Companion object to create the GithubApiService */ companion object Factory { fun create(): GithubApiService { val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl("https://api.github.com/") .build() return retrofit.create(GithubApiService::class.java); } } } 

Using this interface and the factory class will look like this:


 val apiService = GithubApiService.create() apiService.search(/* search params go in here */) 

Please note that we did not need to use the “name” of the companion object to refer to the method, we used only the name of the class.


Singletons and related objects in Kotlin


In order to understand what accompanying objects in Kotlin are, we must first understand which ad objects are in Kotlin. The declaration of an object in Kotlin is the way in which a single element is created in Kotlin.


Singletons in Kotlin are as simple as declaring an object and assigning it a name. For example:


 object SearchRepositoryProvider { fun provideSearchRepository(): SearchRepository { return SearchRepository() } } 

Using the above object declaration:


 val repository = SearchRepositoryProvider.provideSearchRepository(); 

Thanks to this, we were able to create a provider that will provide us with an instance of the repository (which will help us connect to the Github API via GithubApiService).


The object declaration is initialized at the first access - the same way Singleton works.


However, companion objects are an object declaration type that corresponds to the companion keyword. Companion objects can be compared to static methods or fields in Java. In fact, if you refer to a companion object with Java, it will look like a static method or field.


The companion object is what is used in the GithubApiService.kt version of Kotlin above.


4. Creating a repository


As we try to abstract our processes as much as possible, we can create a simple repository that handles the GithubApiService call and builds the query string.


The query string that meets our specification for this demo application (for finding Java developers in Omsk) using the Github API is the location: Omsk + language: Java, so we will create a method in the repository that will allow us to build this string, passing the location and language as parameters.


Our search repository will look like this:


 class SearchRepository(val apiService: GithubApiService) { fun searchUsers(location: String, language: String): Observable<Result> { return apiService.search(query = "location:$location+language:$language") } } 

String patterns in Kotlin


In the above code block, we used the Kotlin function, called “String templates”, to build our query string. String patterns begin with a dollar sign — $ and the value of the variable following it is concatenated with the rest of the string. This is a similar function for groovy string interpolation.


5. Make a request and get an API response using RxJava


Now that we have set up our response classes, our repository interface, we can now make a request and get an API response using RxJava. This step is similar to how we will do it in Java. In Kotlin code, it looks like this:


 val repository = SearchRepositoryProvider.provideSearchRepository() repository.searchUsers("Omsk", "Java") .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe ({ result -> Log.d("Result", "There are ${result.items.size} Java developers in Lagos") }, { error -> error.printStackTrace() }) 

We made our request and received a response. Now we can do whatever we want with him.


Useful links:



Conclusion


Thus, in this post, we looked at some interesting features / properties of the Kotlin language and how to use them when using Retrofit + RxJava for network calls.


Have been affected:



')

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


All Articles