This article is an English translation from my original article in my blog xurxodev. Most of the mobile applications are based on communication with an API Rest. The integration with an external service is fundamental in mobile development. To have an optimal integration, it is necessary to ensure it by integration tests. With the appearance of Kotlin Multiplatform, there is a very interesting scenario like having a client of a REST API in a multiplatform library and that we can use it from both an Android application and iOS application.
In this blog post, we will review how we can create a REST API client using Kotlin Multiplatform and how to create the integration tests needed to verify that our integration works correctly. A few weeks ago I participated in a mobile testing training of Karumi where we made this katawe will review a Kotlin Multiplatform version. This REST API manages tasks, you will be able to get all the existing tasks, get a task using its identifier, add a new task, update a task or delete an existing task.
The first thing to do is to create the project, you can use Intellij or Android Studio. The detail explanation of how to configure a Kotlin Multiplatform Library is out of the scope of this post but, here yo have the official documentation of Jetbrains: Multiplatform Kotlin library.
The best time to set up CI for a project is at the beginning, so this would be the next step. In this file, we indicate OS X as the operating system where to perform the build. This is necessary to execute the tests that we are going to create in an iOS emulator. And finally, we indicate the script command to run the build task. Among other subtasks, build task will compile the code of the library for the JVM, also for iOS and finally, It will run the tests on both platforms.
We need the next libraries:. Our client contains a HttpClient to make requests and receive by constructor a HttpClientEngine, we will see why further on. The engine can be assigned explicitly or implicitly by artifacts you have included in the build.KotlinConf 2019: Coroutines Case Study - Cleaning Up an Async API by Tom Hanley
Notice that every method returns an Either type, remember that it is a functional programming technique to deal with errors without the use of exceptions.
In more traditional oriented object programming, each of these methods could return exceptions. If the result is satisfactory, we return the right type of the corresponding generic. In case of an error, Ktor returns an exception that we handle in its own method:. To test the integration of our client with the Rest API, we need to verify the following:. To perform these checks we have to simulate server responses and to be able to access in some way the HTTP requests that we have sent.
The first tests we could try are to verify the todos endpoint, for example:. What infrastructure do we need?The async programming in Kotlin has become more and more popular lately. And coroutines are the main reason async programming becoming more popular in Kotlin. So, why bother to learn coroutines? We as programmers love the sequential way to execute a program. So, our app has this line of code that reads some kind of file long file from memory and returns the read content, and that means our app is doing nothing while processing the file.
It is sitting waiting for a response in order to continue. To standard fix this issue, of course, we can call another thread to read the content from file and our app is happy to do other work without being blocked. Now we know, instead of being blocked by the long-running process we can simply call a new thread to do the task.
Subscribe to RSS
We can also spin up multiple threads; each thread one thing at a time. Together these threads allow our app to do multiple things at a time.
If the next generation of programmers makes more intensive use of multithreadingthen the next generation of computers will become nearly unusable. Edward A. Lee, a professor at Berkeley. But beware multithreaded programs are more complicated and typically more error-prone, they include common trouble issues: race-conditions, dead-locks, resource starvation, cpu context-switching, etc….
That means that many threads may be active at the same time in the server. Too many threads can consume a large amount of memory and CPU time just for context-switching. Basically, in an asynchronous world, context is switched only at defined switch points rather than in non-deterministic intervals. Another thing we can use to perform async operation is by using callbacks and futures aka promises.
The Java8 CompletableFuture has a whenComplete method that installs a callback to wait for completion without blocking, thus making it usable for asynchronous programming.
The login method essetianlly executes and returns immedialtely allowing the app to do other things instead of sitting there waiting for response. But what if after we get the user object in onSuccess method of Callback we need to make another asynchronous call for user home feed and user new inbox messages.
We would have to hack around and save the result into some sort of global variables. Which is not good! People in the kotlin community have realized that callbacks and futures are a pain for a long time, and come up with an excellent async kotlin-coroutines library. A coroutine is a new way of asynchronous, non-blocking code that can be thought of as light-weight threads. Coroutines can run in parallel or concurrently, wait for other coroutines and communicate with each other. As soon as you do any IO operation, it just parks the coroutines and resumes any other one that are not blocked by IO.GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
If nothing happens, download GitHub Desktop and try again. If nothing happens, download Xcode and try again. If nothing happens, download the GitHub extension for Visual Studio and try again. This is a small library that provides the Kotlin Coroutines suspending extension Call.
Based on kotlinx. Kotlin 1. Download the JAR :. For a real application you probably want to use some other coroutines builder that does not block a thread, for example launch from kotlinx. If you want to use this library for UI please also check the Guide to UI programming with coroutines. Common await API that returns a Response or throws an exception.
API based on sealed class Result :. Also, Result has a few handy extension functions that allow to avoid when block matching:. All Result classes also implemented one or both interfaces: ResponseResult and ErrorResult You can use them for access to shared properties of different classes from Result. By wrapping call with kotlinx.
You can read more about concurrent usage of async in the kotlinx. Skip to content. Dismiss Join GitHub today GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up. Kotlin Coroutines await extension for Retrofit Call.For decades, as developers we are confronted with a problem to solve - how to prevent our applications from blocking. Whether we're developing desktop, mobile, or even server-side applications, we want to avoid having the user wait or what's worse cause bottlenecks that would prevent an application from scaling. Let's assume in the code above that preparePost is a long-running process and consequently would block the user interface.
What we can do is launch it in a separate thread. This would then allow us to avoid the UI from blocking. This is a very common technique, but has a series of drawbacks:.
In practical terms, Rx is simply the Observer Pattern with a series of extensions which allow us to operate on the data. In approach it's quite similar to Futures, but one can think of a Future as returning a discrete element, whereby Rx returns a stream. However, similar to the previous, it also introduces a complete new way of thinking about our programming model, famously phrased as.
Kotlin's approach to working with asynchronous code is using coroutines, which is the idea of suspendable computations, i. One of the benefits however of coroutines is that when it comes to the developer, writing non-blocking code is essentially the same as writing blocking code. The programming model in itself doesn't really change. This code will launch a long-running operation without blocking the main thread.
The preparePost is what's called a suspendable functionthus the keyword suspend prefixing it. What this means as stated above, is that the function will execute, pause execution and resume at some point in time.Kotlin coroutines are still in the experimental phase, but they are quickly becoming one of the most popular features for developers that want to use asynchronous programming methods.
Most mobile apps have to perform long-running or intensive operations — such as network calls or database operations — at some point. At any one time, your app might be playing a video, buffering the next section of video, and monitoring the network for possible interruptions, all while staying responsive to user input. Android executes all its tasks by default on a single main UI thread, one task at a time.
If this thread ever becomes blocked, your application is going to freeze, and may even crash. Creating a thread is also an expensive process. Several solutions aim to simplify multi-threading on Android, such as the RxJava library and AsyncTaskproviding ready-made worker threads. Even with the help of third party libraries and helper classes, multi-threading on Android is still a challenge.
Think of coroutines as a lightweight alternative to threads. You can run thousands of them without any noticeable performance issues.
While the above code will run without any issues, spawningthreads will likely result in your application crashing with an OutOfMemory error.
Asynchronous code can quickly become complicated, but coroutines let you express the logic of your asynchronous code sequentially.
Simply write your lines of code, one after the other, and the kotlinx-coroutines-core library will figure out the asynchrony for you. Handling asynchronous code execution usually requires some form of callback. As callbacks increase, your code becomes more complex and difficult to read.
Coroutines provide much more flexibility than plain reactive programming. Android Studio 3.
This checkbox adds basic Kotlin support to your project, but since coroutines are currently stored in a separate kotlin. While coroutines still have experimental status, using any coroutine-related features will cause the Kotlin compiler to issue a warning.
The launch function creates a new coroutine and returns a Job object without an associated result value. Once the asynchronous operation inside async completes, the coroutine is resumed and can continue as normal.
Here, myMethod result is executed with the result of the asynchronous operation the result returned by the block of code inside async without having to implement any callbacks.Think of Coroutines as lightweight threads that are used to perform tasks asynchronously, a. They are natively supported by many programming languages, such as Go, Python, Perl, Ruby, Kotlin, etc.
Although Coroutines are used in general-purpose programming quite often, this article will primarily focus on Coroutines in an Android context. This article will be a guide on how to implement Coroutines and the know-hows on integrating them into your existing Android app.
If you recently got a new phone, chances are it has a refresh rate of at least 60Hz. This means that your app has 16ms to perform tasks on the Android main thread. Keep in mind that there are phones with higher refresh rates, and this time period will vary.
Kotlin Coroutines enhance asynchronous programming by being lightweight and essentially faster than a thread as they are stackless. Additionally as most phones have at least 4 cores these days, it might be a good idea to put all 4 cores to work! Note : At the time of writing this article, the latest version of Kotlin was 1.
Simply put, blocking functions are synchronous. If two or more functions execute one after the other, in the order they were invoked, they are said to be blocking functions. The above two functions fun A and fun Bif made suspending functions, would be represented like this:. To sum it up, a suspending function is a function whose execution can be started, paused and resumed again. In Kotlin, a suspending function can only be invoked from another suspending function.
To declare a suspending function in Kotlin, just add the suspend modifier to your function. Before we get to using Coroutines in our app, it is very important to understand how Coroutines work under the hood and get a good understanding of the components that are responsible for launching and executing a Coroutine.
CoroutineContextas the name indicates, defines the context in which your Coroutine runs. This is similar to the Context of Activity or Fragmentand is used to manage lifecycle-related operations, proper threading, debugging, and handling exceptions.
This way you can restrict the scope of your Coroutine to the lifecycle of Activity or Fragment. Coroutine Builders are extension functions on your CoroutineScope that let you build your Coroutine and manage its execution.
In Kotlin, we have a bunch of Coroutine Builders. The two most used Coroutine Buillders are launch and async. We will cover this in detail later in this article. CoroutineDispatcher is an abstract class that is responsible for launching your Coroutines. There are 4 Dispatchers that a CoroutineDispatcher can use to launch your Coroutine:. The entire list of Coroutine Builders can be found herebut for brevity purposes, we shall only talk about launch and async Coroutine Builders.
The launch Coroutine Builder launches a new coroutine without blocking the current thread and returns a reference to the coroutine as a Job. Here is the function definition for launchas described in the official documentation:. Here, the Job class is used to represent a job of a Coroutine and is also used to manage the execution of said Coroutine.
Another noteworthy thing here is that the launch Coroutine Builder is actually an extension function on CoroutineScope. We will see how this ties into lifecycle aware components later.
Main dispatcher, and one with the Dispatchers. IO dispatcher.I started to use them some months ago and, after some attempts, I was quite happy with the final result. For example this is the code of a ViewModel that checks the existence of a token in the shared preferences and executes two Retrofit calls EDIT: updated to Coroutines 0.
The load method checks the shared preferences and if a token is not available updates the UI with a loading message and execute a server call to retrieve it. Then it updates again a loading message and executes another server call, the result is shown in the UI.
Thanks to the coroutines every single task is executed in the right thread:. Everything seemed good, an asynchronous task written in the same way of a synchronous one!
But there was something strange: a background task launched using the Main coroutine context. A lot of material about the coroutines is available, the official guide is a must read but there are many interesting posts on the web.
For example, reading these two I learned something new about the coroutines and some extra doubts about my code arose :. EDIT: since version 0. EDIT: valid until version 0.
Asynchronous Programming In Kotlin
This problem can be solved in two ways:. The cancellation of the external coroutine will be propagated to all the children. In our example this is not a big issue because we are using nested coroutines just to manage shared preferences. In the previous example we are using the async method to execute something in a background thread:.
This syntax is valid but we are creating a new coroutines using async and immediately waiting for the result using await. There is a simpler and more efficient way to achieve the same result: the withContext method. We can refactor the code moving the withContext invocation to TokenHolder class this class uses a delegate to manage the shared preferences, you can find the details in my previous post :.
The loadToken and saveToken methods must be defined as suspendin this way we are forcing the execution of these methods inside a coroutine context.
Thanks to this keyword and to the IO dispatcher used inside the method we are sure that the shared preferences will never be accessed in the Android main thread. After this refactoring we can simplify the code of our example:. We have already seen that the api calls are executed in a background thread and that the UI is updated on the main thread.
The first log is executed at the beginning of a launch block so it will be executed on the main thread. Executing the code we can see in the log something similar to this snippet:. So the computation goes back and forth between the main thread and some background threads, it:. Ok, coroutines are lightweight but the less we use the main thread the better!
In this second example the main thread is used only when necessary and there are fewer switches between a background thread and the main thread.
Retrofit 2 – Synchronous and asynchronous call example
We can simplify the code moving the withContext invocation to the updateUi method:. After this refactoring we are sure that the UI will be always updated in the main thread. Do you remember the error message Only the original thread that created a view hierarchy can touch its views? The release 2. Looking a the source code we can see that this scope uses a Job connected to the ViewModel lifecycle, similar to the previous example of this post, but it uses the Main dispatcher instead of IO. So is this post still useful?
All the theory explained in this post is still valid but viewModelScope is definitely the way to go to use coroutines in a ViewModel. So can we rewrite the previous example using this new scope and avoiding to execute too much code on the main thread? The solution is easy, an extra withContext IO block can be used to execute multiple suspending methods without going back and forth from a background thread to the main thread:. In this post we have used a lot three coroutines methods: asynclaunch and withContext.
Here there is a recap of how to use them:.