- Using Kotlin, RxJava 2 and Retrofit to consume REST API on Android
- Tech Stack
- Kotlin
- RxJava 2
- Retrofit
- The Process
- Consuming REST api with Retrofit
- Introducing endpoints as RxJava Flowables
- Error handling
- Polishing it with extension methods
- Conclusion
- Retrofit на Android с Kotlin
- 0. Установка
- 1. Добавление зависимостей
- 2. Создание классов данных
- Классы данных в Котлине
- 3. Создание API-интерфейса
- Синглтоны и сопутствующие объекты в Котлине
- 4. Создание репозитория
- Строковые шаблоны в Котлине
- 5. Делаем запрос и получаем ответ API при помощи RxJava
- Полезные ссылки:
- Заключение
- Connect to an API With Retrofit, RxJava 2, and Kotlin
- What We’ll Be Building
- Why Should I Use RxJava for My API Calls?
- Authenticating With an API Key
- Create Your Application: Adding Dependencies
- 1. RecyclerView
- 2. Gson Converter
- 3. The RxJava Adapter
- 4. The RxAndroid Library
- . But Not RxKotlin
- Add the Project Dependencies
- Request Access to the Internet
- Define Your HTTP Endpoints
- Creating a Model With Kotlin’s Data Class
- Building the Retrofit Instance
- Displaying the Cryptocurrency API Data
- Creating a Scrollable List
- Binding Data With Android Adapters
- Testing Your Retrofit and RxJava 2.0 App
- Conclusion
Using Kotlin, RxJava 2 and Retrofit to consume REST API on Android
Recently I decided to create a pet project which would help me and my girlfriend split house chores.
The idea was to define a set of chores and assign them to users periodically.
Every night, chores for the upcoming day are distributed to users (based on what they have done in the past).
Tech Stack
I am a backend developer and my go-to language is Scala, so the choice for server side was quite clear.
For client side I decided to go with Android since doing house chores is highly mobile activity.
Considering nature of house chores, mobile client seemed like a good idea.
The remaining decision was language and stack for it.
Kotlin
Kotlin is JVM language which makes it compatible with existing Java libraries (RxJava and Retrofit being some of them).
Apart from that Kotlin is more functional than Java which helps to deal with the approach imposed by RxJava.
It is already stable and has an excellent IDE support.
Kotlin surprised me also with its great compile time (almost matching Java).
RxJava 2
Almost every mobile app has at least two asynchronous sources of data — user input and IO (network/storage).
UI needs to be responsive at all times — that’s why they need to be handled on a different threads.
We still need a way to glue these sources with the app.
Traditionally it is done by listening to user input/IO and then changing state as a reaction to these events.
It usually leads to callback hell and complex state management.
RxJava is the solution to this problem. It provides a way to chain and combine asynchronous flows of data.
Retrofit
This is a type safe http client, handling all serialization and deserialization into user defined classes behind the scenes.
I’ve used Retrofit before and had very positive experience with it.
Apart from that, it integrates nicely with RxJava.
The Process
Consuming REST api with Retrofit
The very first step was adding and getting chores from the server. Using retrofit, we can define http endpoints in a type safe way:
In Kotlin, DTOs can be defined as immutable data classes:
That’s it. No equals, hashcode, constructors or toString. It’s all there under the hood.
Using shiny, new interface it’s possible to add chores and fetch them from a server.
Wow, this sucks. It’s the very first example and we’ve already run into nested callbacks.
Apart from that, what would happen if some other part of app also required updated chores? We would have to make another request.
Ideally all interested components should be notified about new chores, regardless of what initiated them.
Let’s go ahead and make this code better.
Introducing endpoints as RxJava Flowables
This is where RxJava becomes useful.
There is an adapter for retrofit that allows to define endpoints as Flowables ( Flowable is RxJava2’s replacement for Observable ):
Once the endpoints are defined, it’s a good idea to specify which scheduler should be used for doing IO and which for receiving result:
It’s now possible for anyone to subscribe to choresFlowable and get chores upon subscription:
It would also be great if all subscribers of choresFlowable received newest chores when a new chore is added.
Currently the data is pulled once, upon subscription.
RxJava is all about chaining and composing, so achieving it becomes really easy:
choresChanged is PublishProcessor . This is an RxJava component that allows to manually emit items to downstream.
By calling choresChanged.onNext it sends the item (Unit) down the stream. This signals a need for chores to be updated.
choresChanged.flatMap < backend.getChores() >— after choresChanged emits an empty item, we need to map it into chores.
We do that by calling getChores endpoint, which also returns Flowable .
To avoid nested Flowables, flattening is required ( flatmap = map + flatten )
What happens is that when addChore is invoked, POST chores http endpoint is called.
Once the response comes back from the server, choresChanged PublishProcessor emits a new empty ( Unit ) item.
This triggers GET chores http call, whose result is passed to all subscribers of choresFlowable .
We have no nested callbacks. Anyone can subscribe to choresFlowable , get items on subscription and also each time someone adds a new chore.
This is great! Btw a good place to subscribe to a flowable is Presenter, if you are using MVP.
Error handling
What about error handling?
It’d be nice to have one global error handler for all http errors.
In such handler we could log errors, display a toast and suppress throwable so the app doesn’t crash.
Flowable has onErrorResumeNext method, which does exactly that.
All we have to do is create a new PublishProcessor and invoke it from onErrorResumeNext :
Polishing it with extension methods
As you can see, the lambda argument for onErrorResumeNext is a bit verbose.
In java we could write a method that wraps the existing Flowable and adds error handling:
There is, however, a better way to do this in Kotlin using extension functions.
Basically, what they allow to do is define a function for existing type and call it as if it was part of that type.
You could use it to write extensions for existing collections api or even another String utils library.
There is already RxKotlin library, which uses this concept extensively.
In our case we could utilize this feature to define withErrorHandling function on Flowable type:
The best part is the function can be used on any Flowable object so we can reuse it for other endpoints too.
Conclusion
A few years ago Android development was really painful.
Java 7 forcing us to create an infinite amount of anonymous classes, weird APIs, slow emulator, eclipse and sluggish edit->compile->run cycle.
Today with many libraries, Android Studio and Kotlin I must say the process is way more enjoyable.
Given my short experiment with Kotlin I honestly see no reason why new projects should still use Java.
I had experienced absolutely no issues with Kotlin, regarding bugs / compilation times or IDE support.
Coming from Scala I missed a few traits here and there (I prefer Option monad instead of nullable values for instance), but that’s just style preference.
The learning curve is also gentle, so I believe any Java developer could pick it in a matter of day.
Источник
Retrofit на Android с Kotlin
Одним из самых захватывающих объявлений на Google I/O в этом году стала официальная поддержка Kotlin для разработки под Android.
Котлин на самом деле не новый язык, ему уже >5 лет и он довольно зрелый. Здесь вы можете получить более подробную информацию о языке
Я планирую поделиться некоторыми «практиками» использования Kotlin в разработке Android.
Retrofit — очень популярная библиотека для работы с сетью, и она широко используется в сообществе разработчиков. Даже Google использует его в своих образцах кода.
В этой статье я расскажу о том, как использовать REST API в ваших приложениях с помощью Retrofit + Kotlin + RxJava. Мы будем использовать API Github для получения списка разработчиков Java в Омске, Россия. Также, я затрону некоторые особенности языка программирования и расскажу о том, как мы можем применять их к тому, что мы, разработчики Android, делаем ежедневно — вызывать API.
0. Установка
В Android Studio 3.0 (Preview) теперь есть встроенная поддержка Kotlin, без ручной установки плагинов. Отсюда можно установить preview-версию.
1. Добавление зависимостей
Чтобы использовать Retrofit, вам нужно добавить зависимости в файл build.gradle:
RxJava2 поможет сделать наши вызовы реактивными.
GSON-конвертер будет обрабатывать десериализацию и сериализацию тел запроса и ответа.
RxAndroid поможет нам с привязкой RxJava2 к Android.
2. Создание классов данных
Как правило, следующим шагом является создание классов данных, которые являются POJO (Plain Old Java Objects) и которые будут представлять ответы на вызовы API.
С API Github пользователи будут представлены как объекты.
Как это будет выглядеть на Kotlin:
Классы данных в Котлине
Классы данных в Kotlin — это классы, специально разработанные для хранения данных.
Компилятор Kotlin автоматически помогает нам реализовать методы equals (), hashCode () и toString () в классе, что делает код еще короче, потому что нам не нужно это делать самостоятельно.
Мы можем переопределить реализацию по умолчанию любого из этих методов путем определения метода.
Отличной особенностью является то, что мы можем создавать результаты поиска в одном файле Kotlin — скажем, SearchResponse.kt. Наш окончательный класс ответа на поиск будет содержать все связанные классы данных и выглядеть следующим образом:
SearchResponse.kt
3. Создание API-интерфейса
Следующим шагом, который мы обычно делаем в Java, является создание интерфейса API, который мы будем использовать для создания запросов и получения ответов.
Как правило, в Java я хотел бы создать удобный «фабричный» класс, который создает службу API, когда это необходимо, и я бы сделал что-то вроде этого:
GithubApiService.java
Чтобы использовать этот интерфейс, мы делаем следующие вызовы:
Чтобы повторить тоже самое в Котлине, у нас будет эквивалентный интерфейс GithubApiService.kt, который будет выглядеть так:
GithubApiService.kt
Использование этого интерфейса и фабричного класса будет выглядеть так:
Обратите внимание, что нам не нужно было использовать «имя» сопутствующего объекта для ссылки на метод, мы использовали только имя класса.
Синглтоны и сопутствующие объекты в Котлине
Чтобы понять, какие сопутствующие объекты в Котлине есть, мы должны сначала понять, какие объявления объектов находятся в Котлине. Объявление объекта в Котлине — это способ, которым одиночный элемент создается в Котлине.
Синглтоны в Котлине так же просты, как объявление объекта и присвоение ему имени. Например:
Использование указанного выше объявления объекта:
Благодаря этому мы смогли создать поставщика, который предоставит нам экземпляр репозитория (который поможет нам подключиться к API Github через GithubApiService).
Объявление объекта инициализируется при первом доступе — так же, как работает Singleton.
Однако, объекты-компаньоны — это тип объявления объекта, который соответствует ключевому слову companion. Объекты Companion можно сравнить с статическими методами или полями на Java. Фактически, если вы ссылаетесь на объект-компаньон с Java, он будет выглядеть как статический метод или поле.
Сопутствующий объект — это то, что используется в версии GithubApiService.kt Kotlin выше.
4. Создание репозитория
Поскольку мы стараемся как можно больше абстрагировать наши процессы, мы можем создать простой репозиторий, который обрабатывает вызов GithubApiService и строит строку запроса.
Строка запроса, соответствующая нашей спецификации для этого демонстрационного приложения (для поиска разработчиков Java в Омске) с использованием API Github, — это местоположение: Omsk + language: Java, поэтому мы создадим метод в репозитории, который позволит нам построить эту строку, передавая местоположение и язык в качестве параметров.
Наш поисковый репозиторий будет выглядеть так:
Строковые шаблоны в Котлине
В блоке вышеприведенного кода мы использовали функцию Kotlin, называемую «String templates», чтобы построить нашу строку запроса. Строковые шаблоны начинаются со знака доллара — $ и значение переменной, следующей за ней, конкатенируется с остальной частью строки. Это аналогичная функция для строковой интерполяции в groovy.
5. Делаем запрос и получаем ответ API при помощи RxJava
Теперь, когда мы настроили наши классы ответов, наш интерфейс репозитория, теперь мы можем сделать запрос и получить ответ API с помощью RxJava. Этот шаг похож на то, как мы будем делать это на Java. В коде Kotlin это выглядит так:
Мы сделали наш запрос и получили ответ. Теперь можем делать с ним все, что захотим.
Полезные ссылки:
Заключение
Таким образом, в этом посте мы рассмотрели некоторые интересные возможности/свойства языка Kotlin и способы их применения при использовании Retrofit + RxJava для сетевых вызовов.
- Классы данных
- Объявления объектов
- Сопутствующие объекты
- Строковые шаблоны
- Взаимодействие с Java
Источник
Connect to an API With Retrofit, RxJava 2, and Kotlin
Today, it’s pretty common for mobile apps to exchange data with remote servers, using web Application Programming Interfaces (APIs).
Whether it’s checking for new emails using the Gmail API, searching for events in the local area with the Ticketmaster API, or leveraging the user’s Spotify history to recommend new music, APIs (usually REST APIs) provide access to a wealth of information that you can use in your app.
Communicating with remote servers has become such an important part of modern mobile development that there are countless libraries dedicated to helping you make network calls, but Retrofit is one of the most widely used networking libraries for Android.
In this article, I’ll show you how to retrieve data from a remote API, using Retrofit and the free Nomics Cryptocurrency & Bitcoin API.
Once you’ve retrieved some data, you’ll want to put it to good use! In Android, this often involves forwarding the data to Android’s all-important main UI thread, ready to display in your app’s UI, or transforming the data in some way, such as filtering or combining it. Conveniently, you can do all of these things with the RxJava library, so we’ll be using Retrofit and RxJava side by side in our project.
By the end of this article, you’ll have created an app that retrieves data from a remote API using Retrofit, converts that data into RxJava’s Observable format, and then manipulates that data using a selection of RxJava and RxAndroid operators and schedulers.
What We’ll Be Building
There’s no shortage of APIs out there, but to help keep things straightforward, we’ll be using the free Nomics Cryptocurrency & Bitcoin API to retrieve a list of cryptocurrencies and their market prices for the last recorded trade. I’ll then use a RecyclerView to display this information in our app.
To issue a Retrofit request, we’ll need to create the following:
- A Retrofit class. This is where you’ll create a Retrofit instance, add a converter (we’ll be using Gson), and then specify the base URL that your app should use for all of its HTTP requests.
- A data class. This class represents the responses for each of your app’s API calls.
- An API interface. This is where you describe each Retrofit request that you want to make.
By the end of this tutorial, you’ll have a project that looks something like this:
Why Should I Use RxJava for My API Calls?
RxJava is an open-source, JVM-compatible implementation of the ReactiveX library that’s designed to help you work with asynchronous streams of data in a reactive programming style, and without having to write a ton of callbacks.
There are many benefits to using RxJava in your Android projects, but some of the most important include:
- Simplified code. RxJava lets you describe what you want to achieve, rather than writing a list of instructions for your application to work through. This approach typically results in more concise, human-readable code that’s easier to maintain and less prone to errors.
- Consistency. RxJava may be a data-focused library, but its definition of “data” is pretty broad and includes things like variables, caches, properties, and even user input events such as clicks and swipes. Since RxJava treats pretty much everything as data, it provides a consistent workflow that you can use across your application, in lots of different scenarios.
- Multithreading made easy. Modern mobile apps must be able to multitask, but as a single-threaded environment, Android isn’t exactly a natural born multitasker! Android does provide several built-in tools for creating additional threads, but none of these solutions are particularly easy to work with, and they can quickly result in complex code that’s susceptible to performance problems such as memory leaks. By adding RxJava to your project, you get access to subscribeOn and observeOn operators, which make it much easier to create and manage additional threads.
- Complex data transformations. RxJava has an enormous collection of operators that you can use to modify, filter, merge and transform the data that’s being emitted by your RxJava Observables. Applying an operator to an Observable typically returns another Observable, so if you can’t find the perfect operator for your project, then you can just keep applying operators to an Observable until you get exactly the results you want.
For more information about the benefits of using RxJava in your Android projects, check out our Get Started With RxJava 2 article.
Authenticating With an API Key
Many APIs require you to include a unique API key in your HTTP requests. These keys allow the company or individual behind the API to track the requests associated with your project, which is handy for enforcing usage restrictions or if the API’s creator simply wants some insight into how their API is being used.
When querying the Nomics Cryptocurrency & Bitcoin API, you’ll need to incorporate a unique API key into your request, so let’s generate this key now:
- In your web browser, head over to the Nomics website.
- Find the Get Free API Key button, and give it a click.
- Check the Terms and Conditions, and if you’re happy to proceed then complete the form.
- Select Complete Order. After a few moments, you should receive an email containing your unique API key.
Create Your Application: Adding Dependencies
Create a new Android application with the settings of your choice, but when prompted, opt to Include Kotlin support.
Next, open your build.gradle file and add all the libraries we’ll be using throughout this project. In addition to Retrofit and RxJava 2.0, we’ll need the following:
1. RecyclerView
After retrieving our data, we’ll display it in a list, using RecyclerView .
2. Gson Converter
Most of the time, the server’s response will be mapped to a language-neutral format, such as JSON, so your app will need to serialize and deserialize the JSON data. Out of the box, Retrofit can only deserialize HTTP bodies into OkHttp’s ResponseBody type, but you can support other types by outsourcing the conversion to independent converters.
There’s a wide range of converters available, but in this tutorial I’ll be using Gson, which converts JSON into the equivalent Java objects.
3. The RxJava Adapter
To create interface methods that are capable of returning RxJava types, we’ll need to use the Retrofit adapter for RxJava.
4. The RxAndroid Library
The RxAndroid library provides some Android specific bindings for RxJava, most notably AndroidSchedulers.mainThread .
In Android, you can only update your app’s UI from the main UI thread. If your users are going to see any cryptocurrency data, then you’ll need to switch to the main UI thread at some point.
You can quickly and easily schedule code to run on Android’s main UI thread by using RxJava’s observeOn operator in combination with RxAndroid’s AndroidSchedulers.mainThread scheduler:
To use RxAndroid in your project, you’ll need the following project dependency:
. But Not RxKotlin
At this point, you may be wondering why we’re coding in Kotlin but using RxJava, when there is a dedicated RxKotlin library available.
Since Kotlin is 100% interoperable with Java, the majority of Java libraries are compatible with Kotlin, and RxJava is no exception! You could use RxJava and RxKotlin in your project, but to help keep things simple, I’ll be sticking to RxJava throughout this tutorial. If you’re interested in learning more about RxKotlin, then you’ll find lots of information in my article on Kotlin Reactive Programming With RxJava and RxKotlin.
Add the Project Dependencies
After adding all these project dependencies, your build.gradle file should look something like this:
Request Access to the Internet
Since our app will be communicating with a remote server, it needs permission to access the Internet. Open your project’s Manifest and add the following:
Note that since android.permission.INTERNET is categorised as a safe permission, we don’t need to request it at runtime.
Define Your HTTP Endpoints
Next, we need to create an interface where we describe our HTTP requests:
- Select File >New >Kotlin File/Class from the Android Studio toolbar.
- Name this file GetData.
- Open the dropdown menu, and select Interface.
- Click OK.
Each request needs to include at least one HTTP annotation, which indicates how this request should be handled. Retrofit supports annotations for all the standard request types, but we’ll only be using the @GET annotation, since we’re retrieving data from the server.
We also need to describe the endpoint, which is the URL we’re retrieving data from. In our app, this is https://api.nomics.com/v1/markets/prices, which consists of a base URL (https://api.nomics.com/v1/) and a relative URL (prices). We’ll define the base URL elsewhere in our project, so for now we just need to worry about the relative URL.
If the API in question doesn’t require an API key, then declaring the base and relative URL should be enough, but since the Nomics API does require a key, we need to incorporate this information into our request.
This process can vary between APIs, so you should always refer to your API’s documentation for more information. In particular, be on the lookout for any section marked Authentication, as this is often where you’ll find instructions relating to API keys. The Nomics API documentation is a perfect example of this, as it has a dedicated Authentication section that describes how you should incorporate your key in the following format:
Combining the @GET annotation, relative URL, and your API key gives us the following:
I’ll fetch the API data using Kotlin’s getData() function. Since we want this function to emit RxJava Observables, we need to define our endpoint as a valid RxJava type:
Here’s the completed interface:
Make sure you replace YOUR-API-KEY-HERE with your own key!
Creating a Model With Kotlin’s Data Class
Next, we need to create a data class that represents the response to each of our API calls:
- Select File >New >Kotlin File / Class from the Android Studio toolbar.
- Name this class RetroCrypto, and then click OK.
- Open your new RetroCrypto class.
If you’ve previously performed Retrofit calls using Java, then this is one area where Kotlin is much more concise than the equivalent Java, thanks to data classes.
In Kotlin, a data class is a class that’s designed solely to hold some data. The Kotlin compiler implements the required hashCode() , equals() and toString() methods automatically, so you can create a data model class in a single line of code.
Open your new RetroCrypto file and add the following:
Building the Retrofit Instance
To send network requests, we need to use the Retrofit.Builder class to create a Retrofit instance, where we’ll call our endpoint and retrieve the cryptocurrency information.
Once we’ve built our Retrofit object, we need to:
- Set the base URL. Before you can call the build() method on Retrofit.Builder , you need to have at least defined the base URL.
- Set the default converter, using the addConverterFactory() method. Once you’ve set up the Gson converter, it’ll translate the JSON response for you automatically.
- Apply the adapter. Retrofit ships with a default adapter for executing Call instances, but you can apply one or more additional adapters by supplying an instance of that adapter when you’re building the Retrofit instance. To use RxJava alongside Retrofit, we need to add RxJava2CallAdapterFactory as the call adapter, using .addCallAdapterFactory .
This gives us the following:
By default, an Observable emits its data on the thread where the subscription was declared, which in Android is typically the main UI thread. However, for the best results, your app should only perform UI-related work on the UI thread, so we’ll be using RxJava’s subscribeOn and an accompanying Scheduler to create an alternative thread where the Observable should execute:
Next, we’ll use the observeOn operator, plus RxAndroid’s AndroidSchedulers.mainThread Scheduler to send the Observable’s notifications to Android’s main UI thread, ready to display the retrieved data in our app’s UI.
For a more detailed look at subscribing to Observables in Kotlin, check out my post on Kotlin Reactive Programming With RxJava and RxKotlin.
In the following snippet, I’m also using the handleResponse() method to handle the data we’ll receive, following a successful network operation:
The above code returns a Disposable —if you have previous experience of RxJava 1.0, then disposables are essentially RxJava 2.0’s version of subscriptions.
When you’ve finished with a disposable/subscription, you must dispose of it to avoid memory leaks. We can make this cleanup process easier by adding all of our disposables to a CompositeDisposable , which is a container that can hold multiple disposables. In the above code, we’re initializing RxJava’s CompositeDisposable , and then adding each disposable to the CompositeDisposable , using the add() method.
Then, we simply need to clear the CompositeDisposable during our project’s onDestroy() method:
Here’s the completed class:
Displaying the Cryptocurrency API Data
At this point, our app can successfully retrieve data from the Nomics API, so our final task is displaying this data to the user, via a RecyclerView.
To implement a RecyclerView, we need the following:
- A RecyclerView widget.
- A custom XML layout that the RecyclerView can use to display each of its items.
- An adapter, which binds the data to your RecyclerView .
Creating a Scrollable List
Let’s start by adding a RecyclerView widget to our activity_main.xml file:
Now that we have our RecyclerView widget, we need to define the layout for each row within that RecyclerView . I’m going to create a simple layout consisting of two TextView s, where I’ll display the name and the price for each cryptocurrency retrieved from the Nomics API:
- Control-click your project’s res/layout folder.
- Select New >Layout resource file.
- Name this file row_layout, and then click OK.
Open the row_layout.xml file, and add the following:
Our RecyclerView will now use this layout for each item in our list.
Binding Data With Android Adapters
The adapter is the component that’s responsible for binding each item to a View within the RecyclerView .
To connect the underlying data model to your app’s UI, you need to extend RecyclerView.Adapter , and then implement the following:
- onCreateViewHolder() . This is where we specify the layout ( R.layout.row_layout ) that each item in the RecyclerView should use, and inflate that layout using LayoutInflater .
- onBindViewHolder() . Called by RecyclerView to display the data at the specified position.
- getItemCount() . Returns the number of items present in the data set.
When you’re working with Views , you can often simplify your code by using Kotlin Android extensions. These extensions allow you to access a layout’s Views directly, by importing them into your class as “synthetic” properties. For example, you can import references to all the Views within your row_layout file, using the following:
At this point, you can access all of row_layout ’s Views , using just their IDs—and without a findViewById() in sight! For example, you can update the text_name widget, using the following:
In this class, I’ll also pass the data as an ArrayList , along with a Listener that I’ll use to handle user input events. Finally, to make our app look a little more interesting, I’ll define an Array of colours and then use them as the background for my RecyclerView items.
Create a new Kotlin class named MyAdapter and then add the following:
Testing Your Retrofit and RxJava 2.0 App
Now it’s time to put your application to the test! Make sure you have an active Internet connection, and then install your app on an Android smartphone or tablet or AVD (Android Virtual Device). As soon as your app launches, Retrofit will retrieve all the available data from the Nomics API, and then display it as part of your RecyclerView .
You can also download the completed project from our GitHub repo.
Conclusion
In this article, I showed you how to retrieve data from an API using Retrofit, convert that data into RxJava 2.0’s Observable format, and then display it in a RecyclerView .
If you want to explore more APIs, then you’ll find a list of free, public APIs over at GitHub, or you can learn more about RxJava by checking out our series on Getting Started With RxJava 2 for Android, or by taking a look at our Kotlin Reactive Programming series.
Источник