• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer
Codemotion Magazine

Codemotion Magazine

We code the future. Together

  • Magazine
  • Dev Hub
    • Community Manager
    • CTO
    • DevOps Engineer
    • Backend Developer
    • Frontend Developer
    • Web Developer
    • Mobile Developer
    • Game Developer
    • Machine Learning Developer
    • Blockchain Developer
    • Designer – CXO
    • Big Data Analyst
    • Security Manager
    • Cloud Manager
  • Articles
    • Stories
    • Events
  • Sign In
Home » Dev Hub » Mobile Developer » Async code on Kotlin: coroutines VS RxJava
Mobile Developer

Async code on Kotlin: coroutines VS RxJava

Two main approaches to implementing asynchronous code in Kotlin: the first uses coroutines, the second is based on the RxJava library.

Last update August 13, 2020 by Vito Gentile

mobile development developer
Table Of Contents
  • What are coroutines?
  • What is RxJava?
  • A sample service in Kotlin
  • Using service methods
  • Coroutines or RxJava?
  • Conclusions

A lot of Android programmers are now exploring Kotlin, a programming language based on Java and the JVM that is used to develop Android applications. As is often the case with Java-based Android apps, one of the main problems when approaching Android development in Kotlin is the management of asynchronous code. In Java, this has been solved by the AsyncTask class, or the runOnUiThread method. In Kotlin, something different is required.

At Codemotion Milan 2018, Fabio Collini, Google Developer Expert and Senior Android Developer, delivered a speech on how to implement asynchronous code in Kotlin. Specifically, he described two different approaches: the first using coroutines, the second based on a library named ReactiveX Java (or RxJava in short). Both of these approaches allow users to implement and support asynchronous operations, and can be also used both together and interchangeably.
This post provides a quick overview on how these approaches differ from each other.

Before starting, let’s try to understand more clearly the main differences between RxJava and coroutines, and how they can help Kotlin programmers.

What are coroutines?

The concept of coroutine is not strictly related to Kotlin. Coroutines are in fact components that generalize subroutines for non-preemptive multitasking, which allows tasks to suspend and resume their own execution. These components are therefore particularly useful for multi-thread programming, and are also found in other languages such as Python or C#.

In Kotlin, coroutines are implemented within the kotlinx.coroutines library, originally developed by JetBrains. The Kotlin official documentation provides an extensive ‘how to’ guide that is available at this link.

What is RxJava?

RxJava, shorthand for ‘ReactiveX for Java‘, was created by Ben Christensen and David Karnok, with the first version released in November 2014. RxJava has found several applications in the Android world, thanks to its unique features. Indeed, this library allows easy termination of subscription when an activity is ending, thus avoiding memory leaks and the waste of resources derived from working on UI elements that are no longer visible.

Moreover, RxJava is considered one of the most fruitful methods for enabling Reactive Programming in Android development. As we’ll see below, the result is simplified implementation of concurrency and the asynchronous tasks inherent in mobile programming.

Although it is also available for Java,this article will focus on how to use RxJava to implement mobile apps in Kotlin.

A sample service in Kotlin

Fabio Collini started the discussion about using RxJava or coroutines by showing a sample interface for a service aimed at obtaining information from StackOverflow. Since such a service is made up of asynchronous methods, it is perfect for our purposes.

The first question is therefore how to define methods that are asynchronous? With RxJava, we need to use a Single class as type for the return value:

interface StackOverflowService {
	@GET("/users")
	fun getTopUsers(): Single<List<User>>
    
	@GET("/users/{userId}/badges")
	fun getBadges(
    		@Path("userId") userId: Int
	): Single<List<Badge>>
    
	@GET("/users/{userId}/top-tags")
	fun getTags(
   		@Path("userId") userId: Int
	): Single<List<Tag>>
}

This allows use of the subscribe method in order to wait for the response.
With coroutines, there are two possibilities: the first is similar to the above, but uses the Deferred class:

interface StackOverflowService {
	@GET("/users")
	fun getTopUsers(): Deferred<List<User>>
    
	@GET("/users/{userId}/badges")
	fun getBadges(
    		@Path("userId") userId: Int
	): Deferred<List<Badge>>
    
	@GET("/users/{userId}/top-tags")
	fun getTags(
   		@Path("userId") userId: Int
	): Deferred<List<Tag>>
}

However, a recent upgrade of Kotlin allows for declaration of suspending functions, which in practice makes the code appears synchronous, even it is actually the opposite:

interface StackOverflowService {
	@GET("/users")
	suspend fun getTopUsers(): List<User>
    
	@GET("/users/{userId}/badges")
	suspend fun getBadges(
    		@Path("userId") userId: Int
	): List<Badge>
    
	@GET("/users/{userId}/top-tags")
	suspend fun getTags(
   		@Path("userId") userId: Int
	): List<Tag>
}

In what follows, we will consider the latter approach, which makes the code cleaner.

Using service methods

Now, if we want to use the aforementioned service, RxJava and coroutines require different approaches. As mentioned above, RxJava requires using the subscribe method:

class MyViewModel(
	private val service: StackOverflowService
) : ViewModel() {

	private val disposable = CompositeDisposable()

	fun load() {
		disposable +=
			service.getTopUsers()
				.subscribeOn(io())
				.observeOn(mainThread())
				.subscribe(
					{ users -> updateUi(users) },
					{ e -> updateUi(e) }
				)
	}
    
	private fun updateUi(s: Any) {
		//...
	}
    
	override fun onCleared() {
		disposable.clear()
	}
}

The subscribe method accepts two parameters: the first is the one we want to execute, while the second (e -> updateUi(e)) is used in case of errors.

While RxJava is synchronous by default (one consequence of this is that we resorted to subscribe), using coroutines and suspending functions allows us to write code that is automatically interpreted as asynchronous, even if it appears synchronous. To understand this difference, compare the following snippet with the previous one: they are equivalent in functionality.

class MyViewModel(
	private val service: StackOverflowService
) : ViewModel() {

	fun load() {
		viewModelScope.launch {
			try {
				val users = service.getTopUsers()
				updateUi(users)
			} catch (e: Exception) {
				updateUi(e)
			}
		}
	}
    
	private fun updateUi(s: Any) {
		//...
	}
}

Here, viewModelScope simplifies the code, even if it is not available yet using Kotlin. However, an implementation is provided in this link.

In general, even more complicated things are made possible by using coroutines or RxJava. Additional code examples by Fabio Collini are available on GitHub.

Coroutines or RxJava?

Having read this quick overview of coroutines and RxJava, one might ask which solution is the best. In terms of number of methods, RxJava is bigger than a solution based on coroutines only. However, this difference can be eliminated by using Proguard and its code optimization. The following graphs taken from Fabio Collini’s slides show this.

Conclusions

So, which approach should we use for production code?
In order to answer such a question, Fabio Collini proposed the following ‘algorithm’:

  • if you are already using RxJava and it works for you, then use RxJava
  • if the architecture is based on a reactive stream, then use RxJava
  • if the project is multiplatform with Kotlin Native, then use coroutines
  • if the codebase is Java/Kotlin, then use RxJava
  • otherwise, use coroutines

An additional note: consider that coroutines are generally easier to understand, while the learning curve for RxJava is steep. This makes coroutines generally preferable, except in the aforementioned cases.

Tagged as:Codemotion Milan Kotlin Mobile Development

What a Security Engineer & Software Engineer Learned by Swapping Roles
Previous Post
Genetic Algorithms: A Developer’s Perspective
Next Post

Primary Sidebar

Subscribe to our newsletter

I consent to the processing of personal data in order to receive information on upcoming events, commercial offers or job offers from Codemotion.
THANK YOU!

Whitepaper & Checklist: How to Organise an Online Tech Conference

To help community managers and companies like ours overcome the Covid-19 emergency we have decided to share our experience organizing our first large virtual conference. Learn how to organise your first online event thanks to our success story – and mistakes!

DOWNLOAD

Latest

we love founders

Thinking Like a Founder – meet Chad Arimura

CTO

Move Over DevOps, It’s Time for DesignOps and the Role of UX Engineer

Designer - CXO

developer

The State of AI in 2021

Machine Learning Developer

Machine Learning on the Network Edge

The Rise of Machine Learning at the Network Edge

Machine Learning Developer

robot programming

Are You Ready for the FaaS Wars?

Backend Developer

Related articles

  • Become a Mobile Developer and Connect the Virtual and Physical Worlds
  • Flutter for Android Developers explained by Faisal Abid
  • Kotlin loves React
  • The state of Developer Ecosystem in 2019: the rise of Kotlin and React
  • Kotlin, but why?
  • Getting started with Kotlin on Android
  • Kotlin Users Group – Interview with organiser, Jakub Jablonski
  • IoT Innovation and Bluetooth® mesh networks
  • 5 Mobile App Predictions for 2020

Subscribe to our newsletter

I consent to the processing of personal data in order to receive information on upcoming events, commercial offers or job offers from Codemotion.
THANK YOU!

Footer

  • Learning
  • Magazine
  • Community
  • Events
  • Kids
  • How to use our platform
  • About Codemotion Magazine
  • Contact us
  • Become a contributor
  • How to become a CTO
  • How to run a meetup
  • Tools for virtual conferences

Follow us

  • Facebook
  • Twitter
  • LinkedIn
  • Instagram
  • YouTube
  • RSS

DOWNLOAD APP

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions

  • Learning
  • Magazine
  • Community
  • Events
  • Kids
  • How to use our platform
  • About Codemotion Magazine
  • Contact us
  • Become a contributor
  • How to become a CTO
  • How to run a meetup
  • Tools for virtual conferences

Follow us

  • Facebook
  • Twitter
  • LinkedIn
  • Instagram
  • YouTube
  • RSS

DOWNLOAD APP

CONFERENCE CHECK-IN